<!DOCTYPE html>
<!-- saved from url=(0029)chrome-error://chromewebdata/ -->
<html dir="ltr" lang="zh"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  
  <meta name="color-scheme" content="light dark">
  <meta name="theme-color" content="#fff">
  <meta name="viewport" content="width=device-width, initial-scale=1.0,
                                 maximum-scale=1.0, user-scalable=no">
  <title>pan.baidu.com</title>
  <style>/* Copyright 2017 The Chromium Authors
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file. */

a {
  color: var(--link-color);
}

body {
  --background-color: #fff;
  --error-code-color: var(--google-gray-700);
  --google-blue-50: rgb(232, 240, 254);
  --google-blue-100: rgb(210, 227, 252);
  --google-blue-300: rgb(138, 180, 248);
  --google-blue-600: rgb(26, 115, 232);
  --google-blue-700: rgb(25, 103, 210);
  --google-gray-100: rgb(241, 243, 244);
  --google-gray-300: rgb(218, 220, 224);
  --google-gray-500: rgb(154, 160, 166);
  --google-gray-50: rgb(248, 249, 250);
  --google-gray-600: rgb(128, 134, 139);
  --google-gray-700: rgb(95, 99, 104);
  --google-gray-800: rgb(60, 64, 67);
  --google-gray-900: rgb(32, 33, 36);
  --heading-color: var(--google-gray-900);
  --link-color: rgb(88, 88, 88);
  --primary-button-fill-color-active: var(--google-blue-700);
  --primary-button-fill-color: var(--google-blue-600);
  --primary-button-text-color: #fff;
  --quiet-background-color: rgb(247, 247, 247);
  --secondary-button-border-color: var(--google-gray-500);
  --secondary-button-fill-color: #fff;
  --secondary-button-hover-border-color: var(--google-gray-600);
  --secondary-button-hover-fill-color: var(--google-gray-50);
  --secondary-button-text-color: var(--google-gray-700);
  --small-link-color: var(--google-gray-700);
  --text-color: var(--google-gray-700);
  background: var(--background-color);
  color: var(--text-color);
  word-wrap: break-word;
}

.nav-wrapper .secondary-button {
  background: var(--secondary-button-fill-color);
  border: 1px solid var(--secondary-button-border-color);
  color: var(--secondary-button-text-color);
  float: none;
  margin: 0;
  padding: 8px 16px;
}

.hidden {
  display: none;
}

html {
  -webkit-text-size-adjust: 100%;
  font-size: 125%;
}

.icon {
  background-repeat: no-repeat;
  background-size: 100%;
}

@media (prefers-color-scheme: dark) {
  body {
    --background-color: var(--google-gray-900);
    --error-code-color: var(--google-gray-500);
    --heading-color: var(--google-gray-500);
    --link-color: var(--google-blue-300);
    --primary-button-fill-color-active: rgb(129, 162, 208);
    --primary-button-fill-color: var(--google-blue-300);
    --primary-button-text-color: var(--google-gray-900);
    --quiet-background-color: var(--background-color);
    --secondary-button-border-color: var(--google-gray-700);
    --secondary-button-fill-color: var(--google-gray-900);
    --secondary-button-hover-fill-color: rgb(48, 51, 57);
    --secondary-button-text-color: var(--google-blue-300);
    --small-link-color: var(--google-blue-300);
    --text-color: var(--google-gray-500);
  }
}
</style>
  <style>/* Copyright 2014 The Chromium Authors
   Use of this source code is governed by a BSD-style license that can be
   found in the LICENSE file. */

button {
  border: 0;
  border-radius: 20px;
  box-sizing: border-box;
  color: var(--primary-button-text-color);
  cursor: pointer;
  float: right;
  font-size: .875em;
  margin: 0;
  padding: 8px 16px;
  transition: box-shadow 150ms cubic-bezier(0.4, 0, 0.2, 1);
  user-select: none;
}

[dir='rtl'] button {
  float: left;
}

.bad-clock button,
.captive-portal button,
.https-only button,
.insecure-form button,
.lookalike-url button,
.main-frame-blocked button,
.neterror button,
.pdf button,
.ssl button,
.enterprise-block button,
.enterprise-warn button,
.managed-profile-required button,
.safe-browsing-billing button,
.supervised-user-verify button,
.supervised-user-verify-subframe button {
  background: var(--primary-button-fill-color);
}

button:active {
  background: var(--primary-button-fill-color-active);
  outline: 0;
}

#debugging {
  display: inline;
  overflow: auto;
}

.debugging-content {
  line-height: 1em;
  margin-bottom: 0;
  margin-top: 1em;
}

.debugging-content-fixed-width {
  display: block;
  font-family: monospace;
  font-size: 1.2em;
  margin-top: 0.5em;
}

.debugging-title {
  font-weight: bold;
}

#details {
  margin: 0 0 50px;
}

#details p:not(:first-of-type) {
  margin-top: 20px;
}

.secondary-button:active {
  border-color: white;
  box-shadow: 0 1px 2px 0 rgba(60, 64, 67, .3),
      0 2px 6px 2px rgba(60, 64, 67, .15);
}

.secondary-button:hover {
  background: var(--secondary-button-hover-fill-color);
  border-color: var(--secondary-button-hover-border-color);
  text-decoration: none;
}

.error-code {
  color: var(--error-code-color);
  font-size: .8em;
  margin-top: 12px;
  text-transform: uppercase;
}

#error-debugging-info {
  font-size: 0.8em;
}

h1 {
  color: var(--heading-color);
  font-size: 1.6em;
  font-weight: normal;
  line-height: 1.25em;
  margin-bottom: 16px;
}

h2 {
  font-size: 1.2em;
  font-weight: normal;
}

.icon {
  height: 72px;
  margin: 0 0 40px;
  width: 72px;
}

input[type=checkbox] {
  opacity: 0;
}

input[type=checkbox]:focus ~ .checkbox::after {
  outline: -webkit-focus-ring-color auto 5px;
}

.interstitial-wrapper {
  box-sizing: border-box;
  font-size: 1em;
  line-height: 1.6em;
  margin: 14vh auto 0;
  max-width: 600px;
  width: 100%;
}

#main-message > p {
  display: inline;
}

#extended-reporting-opt-in {
  font-size: .875em;
  margin-top: 32px;
}

#extended-reporting-opt-in label {
  display: grid;
  grid-template-columns: 1.8em 1fr;
  position: relative;
}

#enhanced-protection-message {
  border-radius: 20px;
  font-size: 1em;
  margin-top: 32px;
  padding: 10px 5px;
}

#enhanced-protection-message a {
  color: var(--google-red-10);
}

#enhanced-protection-message label {
  display: grid;
  grid-template-columns: 2.5em 1fr;
  position: relative;
}

#enhanced-protection-message div {
  margin: 0.5em;
}

#enhanced-protection-message .icon {
  height: 1.5em;
  vertical-align: middle;
  width: 1.5em;
}

.nav-wrapper {
  margin-top: 51px;
}

.nav-wrapper::after {
  clear: both;
  content: '';
  display: table;
  width: 100%;
}

.small-link {
  color: var(--small-link-color);
  font-size: .875em;
}

.checkboxes {
  flex: 0 0 24px;
}

.checkbox {
  --padding: .9em;
  background: transparent;
  display: block;
  height: 1em;
  left: -1em;
  padding-inline-start: var(--padding);
  position: absolute;
  right: 0;
  top: -.5em;
  width: 1em;
}

.checkbox::after {
  border: 1px solid white;
  border-radius: 2px;
  content: '';
  height: 1em;
  left: var(--padding);
  position: absolute;
  top: var(--padding);
  width: 1em;
}

.checkbox::before {
  background: transparent;
  border: 2px solid white;
  border-inline-end-width: 0;
  border-top-width: 0;
  content: '';
  height: .2em;
  left: calc(.3em + var(--padding));
  opacity: 0;
  position: absolute;
  top: calc(.3em  + var(--padding));
  transform: rotate(-45deg);
  width: .5em;
}

input[type=checkbox]:checked ~ .checkbox::before {
  opacity: 1;
}

@media (max-width: 700px) {
  .interstitial-wrapper {
    padding: 0 10%;
  }

  #error-debugging-info {
    overflow: auto;
  }
}

@media (max-width: 420px) {
  button,
  [dir='rtl'] button,
  .small-link {
    float: none;
    font-size: .825em;
    font-weight: 500;
    margin: 0;
    width: 100%;
  }

  button {
    padding: 16px 24px;
  }

  #details {
    margin: 20px 0 20px 0;
  }

  #details p:not(:first-of-type) {
    margin-top: 10px;
  }

  .secondary-button:not(.hidden) {
    display: block;
    margin-top: 20px;
    text-align: center;
    width: 100%;
  }

  .interstitial-wrapper {
    padding: 0 5%;
  }

  #extended-reporting-opt-in {
    margin-top: 24px;
  }

  #enhanced-protection-message {
    margin-top: 24px;
  }

  .nav-wrapper {
    margin-top: 30px;
  }
}

/**
 * Mobile specific styling.
 * Navigation buttons are anchored to the bottom of the screen.
 * Details message replaces the top content in its own scrollable area.
 */

@media (max-width: 420px) {
  .nav-wrapper .secondary-button {
    border: 0;
    margin: 16px 0 0;
    margin-inline-end: 0;
    padding-bottom: 16px;
    padding-top: 16px;
  }
}

/* Fixed nav. */
@media (min-width: 240px) and (max-width: 420px) and
       (min-height: 401px),
       (min-width: 421px) and (min-height: 240px) and
       (max-height: 560px) {
  body .nav-wrapper {
    background: var(--background-color);
    bottom: 0;
    box-shadow: 0 -12px 24px var(--background-color);
    left: 0;
    margin: 0 auto;
    max-width: 736px;
    padding-inline-end: 24px;
    padding-inline-start: 24px;
    position: fixed;
    right: 0;
    width: 100%;
    z-index: 2;
  }

  .interstitial-wrapper {
    max-width: 736px;
  }

  #details,
  #main-content {
    padding-bottom: 40px;
  }

  #details {
    padding-top: 5.5vh;
  }

  button.small-link {
    color: var(--google-blue-600);
  }
}

@media (max-width: 420px) and (orientation: portrait),
       (max-height: 560px) {
  body {
    margin: 0 auto;
  }

  button,
  [dir='rtl'] button,
  button.small-link,
  .nav-wrapper .secondary-button {
    font-family: Roboto-Regular,Helvetica;
    font-size: .933em;
    margin: 6px 0;
    transform: translatez(0);
  }

  .nav-wrapper {
    box-sizing: border-box;
    padding-bottom: 8px;
    width: 100%;
  }

  #details {
    box-sizing: border-box;
    height: auto;
    margin: 0;
    opacity: 1;
    transition: opacity 250ms cubic-bezier(0.4, 0, 0.2, 1);
  }

  #details.hidden,
  #main-content.hidden {
    height: 0;
    opacity: 0;
    overflow: hidden;
    padding-bottom: 0;
    transition: none;
  }

  h1 {
    font-size: 1.5em;
    margin-bottom: 8px;
  }

  .icon {
    margin-bottom: 5.69vh;
  }

  .interstitial-wrapper {
    box-sizing: border-box;
    margin: 7vh auto 12px;
    padding: 0 24px;
    position: relative;
  }

  .interstitial-wrapper p {
    font-size: .95em;
    line-height: 1.61em;
    margin-top: 8px;
  }

  #main-content {
    margin: 0;
    transition: opacity 100ms cubic-bezier(0.4, 0, 0.2, 1);
  }

  .small-link {
    border: 0;
  }

  .suggested-left > #control-buttons,
  .suggested-right > #control-buttons {
    float: none;
    margin: 0;
  }
}

@media (min-width: 421px) and (min-height: 500px) and (max-height: 560px) {
  .interstitial-wrapper {
    margin-top: 10vh;
  }
}

@media (min-height: 400px) and (orientation:portrait) {
  .interstitial-wrapper {
    margin-bottom: 145px;
  }
}

@media (min-height: 299px) {
  .nav-wrapper {
    padding-bottom: 16px;
  }
}

@media (max-height: 560px) and (min-height: 240px) and (orientation:landscape) {
  .extended-reporting-has-checkbox #details {
    padding-bottom: 80px;
  }
}

@media (min-height: 500px) and (max-height: 650px) and (max-width: 414px) and
       (orientation: portrait) {
  .interstitial-wrapper {
    margin-top: 7vh;
  }
}

@media (min-height: 650px) and (max-width: 414px) and (orientation: portrait) {
  .interstitial-wrapper {
    margin-top: 10vh;
  }
}

/* Small mobile screens. No fixed nav. */
@media (max-height: 400px) and (orientation: portrait),
       (max-height: 239px) and (orientation: landscape),
       (max-width: 419px) and (max-height: 399px) {
  .interstitial-wrapper {
    display: flex;
    flex-direction: column;
    margin-bottom: 0;
  }

  #details {
    flex: 1 1 auto;
    order: 0;
  }

  #main-content {
    flex: 1 1 auto;
    order: 0;
  }

  .nav-wrapper {
    flex: 0 1 auto;
    margin-top: 8px;
    order: 1;
    padding-inline-end: 0;
    padding-inline-start: 0;
    position: relative;
    width: 100%;
  }

  button,
  .nav-wrapper .secondary-button {
    padding: 16px 24px;
  }

  button.small-link {
    color: var(--google-blue-600);
  }
}

@media (max-width: 239px) and (orientation: portrait) {
  .nav-wrapper {
    padding-inline-end: 0;
    padding-inline-start: 0;
  }
}
</style>
  <style>/* Copyright 2013 The Chromium Authors
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file. */

/* Don't use the main frame div when the error is in a subframe. */
html[subframe] #main-frame-error {
  display: none;
}

/* Don't use the subframe error div when the error is in a main frame. */
html:not([subframe]) #sub-frame-error {
  display: none;
}

h1 {
  margin-top: 0;
  word-wrap: break-word;
}

h1 span {
  font-weight: 500;
}

a {
  text-decoration: none;
}

.icon {
  -webkit-user-select: none;
  display: inline-block;
}

.icon-generic {
  /* Can't access chrome://theme/IDR_ERROR_NETWORK_GENERIC from an untrusted
   * renderer process, so embed the resource manually. */
  content: image-set(
      url() 1x,
      url() 2x);
}

.icon-info {
  content: image-set(
      url() 1x,
      url() 2x);
}

.icon-offline {
  content: image-set(
      url() 1x,
      url() 2x);
  position: relative;
}

.icon-disabled {
  content: image-set(
      url() 1x,
      url() 2x);
  width: 112px;
}

.hidden {
  display: none;
}

#suggestions-list a {
  color: var(--google-blue-600);
}

#suggestions-list p {
  margin-block-end: 0;
}

#suggestions-list ul {
  margin-top: 0;
}

.single-suggestion {
  list-style-type: none;
  padding-inline-start: 0;
}

.link-button {
  color: rgb(66, 133, 244);
  display: inline-block;
  font-weight: bold;
  text-transform: uppercase;
}

#sub-frame-error-details {

  color: #8F8F8F;

  /* Not done on mobile for performance reasons. */
  text-shadow: 0 1px 0 rgba(255,255,255,0.3);

}

.secondary-button {
  background: #d9d9d9;
  color: #696969;
  margin-inline-end: 16px;
}

.snackbar {
  background: #323232;
  border-radius: 2px;
  bottom: 24px;
  box-sizing: border-box;
  color: #fff;
  font-size: .87em;
  left: 24px;
  max-width: 568px;
  min-width: 288px;
  opacity: 0;
  padding: 16px 24px 12px;
  position: fixed;
  transform: translateY(90px);
  will-change: opacity, transform;
  z-index: 999;
}

.snackbar-show {
  -webkit-animation:
    show-snackbar 250ms cubic-bezier(0, 0, 0.2, 1) forwards,
    hide-snackbar 250ms cubic-bezier(0.4, 0, 1, 1) forwards 5s;
}

@-webkit-keyframes show-snackbar {
  100% {
    opacity: 1;
    transform: translateY(0);
  }
}

@-webkit-keyframes hide-snackbar {
  0% {
    opacity: 1;
    transform: translateY(0);
  }
  100% {
    opacity: 0;
    transform: translateY(90px);
  }
}

.suggestions {
  margin-top: 18px;
}

.suggestion-header {
  font-weight: bold;
  margin-bottom: 4px;
}

.suggestion-body {
  color: #777;
}

/* Decrease padding at low sizes. */
@media (max-width: 640px), (max-height: 640px) {
  h1 {
    margin: 0 0 15px;
  }
  .suggestions {
    margin-top: 10px;
  }
  .suggestion-header {
    margin-bottom: 0;
  }
}

#cancel-save-page-button {
  background-image: url();
  background-position: right 27px center;
  background-repeat: no-repeat;
  border: 1px solid var(--google-gray-300);
  border-radius: 5px;
  color: var(--google-gray-700);
  margin-bottom: 26px;
  padding-bottom: 16px;
  padding-inline-end: 88px;
  padding-inline-start: 16px;
  padding-top: 16px;
  text-align: start;
}

html[dir='rtl'] #cancel-save-page-button {
  background-position: left 27px center;
}

#save-page-for-later-button {
  display: flex;
  justify-content: start;
}

#save-page-for-later-button a::before {
  content: url();
  display: inline-block;
  margin-inline-end: 4px;
  vertical-align: -webkit-baseline-middle;
}

.hidden#save-page-for-later-button {
  display: none;
}

/* Don't allow overflow when in a subframe. */
html[subframe] body {
  overflow: hidden;
}

#sub-frame-error {
  -webkit-align-items: center;
  -webkit-flex-flow: column;
  -webkit-justify-content: center;
  background-color: #DDD;
  display: -webkit-flex;
  height: 100%;
  left: 0;
  position: absolute;
  text-align: center;
  top: 0;
  transition: background-color 200ms ease-in-out;
  width: 100%;
}

#sub-frame-error:hover {
  background-color: #EEE;
}

#sub-frame-error .icon-generic {
  margin: 0 0 16px;
}

#sub-frame-error-details {
  margin: 0 10px;
  text-align: center;
  opacity: 0;
}

/* Show details only when hovering. */
#sub-frame-error:hover #sub-frame-error-details {
  opacity: 1;
}

/* If the iframe is too small, always hide the error code. */
/* TODO(mmenke): See if overflow: no-display works better, once supported. */
@media (max-width: 200px), (max-height: 95px) {
  #sub-frame-error-details {
    display: none;
  }
}

/* Adjust icon for small embedded frames in apps. */
@media (max-height: 100px) {
  #sub-frame-error .icon-generic {
    height: auto;
    margin: 0;
    padding-top: 0;
    width: 25px;
  }
}

/* details-button is special; it's a <button> element that looks like a link. */
#details-button {
  box-shadow: none;
  min-width: 0;
}

/* Styles for platform dependent separation of controls and details button. */
.suggested-left > #control-buttons,
.suggested-right > #details-button {
  float: left;
}

.suggested-right > #control-buttons,
.suggested-left > #details-button {
  float: right;
}

.suggested-left .secondary-button {
  margin-inline-end: 0;
  margin-inline-start: 16px;
}

#details-button.singular {
  float: none;
}

/* download-button shows both icon and text. */
#download-button {
  padding-bottom: 4px;
  padding-top: 4px;
  position: relative;
}

#download-button::before {
  background: image-set(
      url() 1x,
      url() 2x)
    no-repeat;
  content: '';
  display: inline-block;
  height: 24px;
  margin-inline-end: 4px;
  margin-inline-start: -4px;
  vertical-align: middle;
  width: 24px;
}

#download-button:disabled {
  background: rgb(180, 206, 249);
  color: rgb(255, 255, 255);
}

#buttons::after {
  clear: both;
  content: '';
  display: block;
  width: 100%;
}

/* Offline page */
html[dir='rtl'] .runner-container,
html[dir='rtl'].offline .icon-offline {
  transform: scaleX(-1);
}

.offline {
  transition: filter 1.5s cubic-bezier(0.65, 0.05, 0.36, 1),
              background-color 1.5s cubic-bezier(0.65, 0.05, 0.36, 1);

  will-change: filter, background-color;

}

.offline body {
  transition: background-color 1.5s cubic-bezier(0.65, 0.05, 0.36, 1);
}

.offline #main-message > p {
  display: none;
}

.offline.inverted {
  background-color: #fff;
  filter: invert(1);
}

.offline.inverted body {
  background-color: #fff;
}

.offline .interstitial-wrapper {
  color: var(--text-color);
  font-size: 1em;
  line-height: 1.55;
  margin: 0 auto;
  max-width: 600px;
  padding-top: 100px;
  position: relative;
  width: 100%;
}

.offline .runner-container {
  direction: ltr;
  height: 150px;
  max-width: 600px;
  overflow: hidden;
  position: absolute;
  top: 35px;
  width: 44px;
}

.offline .runner-container:focus {
  outline: none;
}

.offline .runner-container:focus-visible {
  outline: 3px solid var(--google-blue-300);
}

.offline .runner-canvas {
  height: 150px;
  max-width: 600px;
  opacity: 1;
  overflow: hidden;
  position: absolute;
  top: 0;
  z-index: 10;
}

.offline .controller {
  height: 100vh;
  left: 0;
  position: absolute;
  top: 0;
  width: 100vw;
  z-index: 9;
}

#offline-resources {
  display: none;
}

#offline-instruction {
  image-rendering: pixelated;
  left: 0;
  margin: auto;
  position: absolute;
  right: 0;
  top: 60px;
  width: fit-content;
}

.offline-runner-live-region {
  bottom: 0;
  clip-path: polygon(0 0, 0 0, 0 0);
  color: var(--background-color);
  display: block;
  font-size: xx-small;
  overflow: hidden;
  position: absolute;
  text-align: center;
  transition: color 1.5s cubic-bezier(0.65, 0.05, 0.36, 1);
  user-select: none;
}

/* Custom toggle */
.slow-speed-option {
  align-items: center;
  background: var(--google-gray-50);
  border-radius: 24px/50%;
  bottom: 0;
  color: var(--error-code-color);
  display: inline-flex;
  font-size: 1em;
  left: 0;
  line-height: 1.1em;
  margin: 5px auto;
  padding: 2px 12px 3px 20px;
  position: absolute;
  right: 0;
  width: max-content;
  z-index: 999;
}

.slow-speed-option.hidden {
  display: none;
}

.slow-speed-option [type=checkbox] {
  opacity: 0;
  pointer-events: none;
  position: absolute;
}

.slow-speed-option .slow-speed-toggle {
  cursor: pointer;
  margin-inline-start: 8px;
  padding: 8px 4px;
  position: relative;
}

.slow-speed-option [type=checkbox]:disabled ~ .slow-speed-toggle {
  cursor: default;
}

.slow-speed-option-label [type=checkbox] {
  opacity: 0;
  pointer-events: none;
  position: absolute;
}

.slow-speed-option .slow-speed-toggle::before,
.slow-speed-option .slow-speed-toggle::after {
  content: '';
  display: block;
  margin: 0 3px;
  transition: all 100ms cubic-bezier(0.4, 0, 1, 1);
}

.slow-speed-option .slow-speed-toggle::before {
  background: rgb(189,193,198);
  border-radius: 0.65em;
  height: 0.9em;
  width: 2em;
}

.slow-speed-option .slow-speed-toggle::after {
  background: #fff;
  border-radius: 50%;
  box-shadow: 0 1px 3px 0 rgb(0 0 0 / 40%);
  height: 1.2em;
  position: absolute;
  top: 51%;
  transform: translate(-20%, -50%);
  width: 1.1em;
}

.slow-speed-option [type=checkbox]:focus + .slow-speed-toggle {
  box-shadow: 0 0 8px rgb(94, 158, 214);
  outline: 1px solid rgb(93, 157, 213);
}

.slow-speed-option [type=checkbox]:checked + .slow-speed-toggle::before {
  background: var(--google-blue-600);
  opacity: 0.5;
}

.slow-speed-option [type=checkbox]:checked + .slow-speed-toggle::after {
  background: var(--google-blue-600);
  transform: translate(calc(2em - 90%), -50%);
}

.slow-speed-option [type=checkbox]:checked:disabled +
  .slow-speed-toggle::before {
  background: rgb(189,193,198);
}

.slow-speed-option [type=checkbox]:checked:disabled +
  .slow-speed-toggle::after {
  background: var(--google-gray-50);
}

@media (max-width: 420px) {
  #download-button {
    padding-bottom: 12px;
    padding-top: 12px;
  }

  .suggested-left > #control-buttons,
  .suggested-right > #control-buttons {
    float: none;
  }

  .snackbar {
    border-radius: 0;
    bottom: 0;
    left: 0;
    width: 100%;
  }
}

@media (max-height: 350px) {
  h1 {
    margin: 0 0 15px;
  }

  .icon-offline {
    margin: 0 0 10px;
  }

  .interstitial-wrapper {
    margin-top: 5%;
  }

  .nav-wrapper {
    margin-top: 30px;
  }
}

@media (min-width: 420px) and (max-width: 736px) and
       (min-height: 240px) and (max-height: 420px) and
       (orientation:landscape) {
  .interstitial-wrapper {
    margin-bottom: 100px;
  }
}

@media (max-width: 360px) and (max-height: 480px) {
  .offline .interstitial-wrapper {
    padding-top: 60px;
  }

  .offline .runner-container {
    top: 8px;
  }
}

@media (min-height: 240px) and (orientation: landscape) {
  .offline .interstitial-wrapper {
    margin-bottom: 90px;
  }

  .icon-offline {
    margin-bottom: 20px;
  }
}

@media (max-height: 320px) and (orientation: landscape) {
  .icon-offline {
    margin-bottom: 0;
  }

  .offline .runner-container {
    top: 10px;
  }
}

@media (max-width: 240px) {
  button {
    padding-inline-end: 12px;
    padding-inline-start: 12px;
  }

  .interstitial-wrapper {
    overflow: inherit;
    padding: 0 8px;
  }
}

@media (max-width: 120px) {
  button {
    width: auto;
  }
}

.arcade-mode,
.arcade-mode .runner-container,
.arcade-mode .runner-canvas {
  image-rendering: pixelated;
  max-width: 100%;
  overflow: hidden;
}

.arcade-mode #buttons,
.arcade-mode #main-content {
  opacity: 0;
  overflow: hidden;
}

.arcade-mode .interstitial-wrapper {
  height: 100vh;
  max-width: 100%;
  overflow: hidden;
}

.arcade-mode .runner-container {
  left: 0;
  margin: auto;
  right: 0;
  transform-origin: top center;
  transition: transform 250ms cubic-bezier(0.4, 0, 1, 1) 400ms;
  z-index: 2;
}

@media (prefers-color-scheme: dark) {
  .icon {
    filter: invert(1);
  }

  .offline .runner-canvas {
    filter: invert(1);
  }

  .offline.inverted {
    background-color: var(--background-color);
    filter: invert(0);
  }

  .offline.inverted body {
    background-color: #fff;
  }

  .offline.inverted .offline-runner-live-region {
    color: #fff;
  }

  #suggestions-list a {
    color: var(--link-color);
  }

  .slow-speed-option {
    background: var(--google-gray-800);
    color: var(--google-gray-100);
  }

  .slow-speed-option .slow-speed-toggle::before,
  .slow-speed-option [type=checkbox]:checked:disabled +
    .slow-speed-toggle::before {
     background: rgb(189,193,198);
  }

  .slow-speed-option [type=checkbox]:checked + .slow-speed-toggle::after,
  .slow-speed-option [type=checkbox]:checked + .slow-speed-toggle::before {
    background: var(--google-blue-300);
  }
}

#main-frame-error:not(.showing-details) #details {
  display: none;
}

@media (min-width: 240px) and (max-width: 420px) and (min-height: 401px),
       (min-height: 240px) and (max-height: 560px) and (min-width: 421px) {
  #main-frame-error.showing-details #main-content,
  #main-frame-error.showing-details .runner-container {
    display: none;
  }
}
</style>


  <script>// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
function assert(value,message){if(value){return}throw new Error("Assertion failed"+(message?`: ${message}`:""))}
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
class LoadTimeData{data_=null;set data(value){assert(!this.data_,"Re-setting data.");this.data_=value}valueExists(id){assert(this.data_,"No data. Did you remember to include strings.js?");return id in this.data_}getValue(id){assert(this.data_,"No data. Did you remember to include strings.js?");const value=this.data_[id];assert(typeof value!=="undefined","Could not find value for "+id);return value}getString(id){const value=this.getValue(id);assert(typeof value==="string",`[${value}] (${id}) is not a string`);return value}getStringF(id,...args){const value=this.getString(id);if(!value){return""}return this.substituteString(value,...args)}substituteString(label,...args){return label.replace(/\$(.|$|\n)/g,(function(m){assert(m.match(/\$[$1-9]/),"Unescaped $ found in localized string.");if(m==="$$"){return"$"}const substitute=args[Number(m[1])-1];if(substitute===undefined||substitute===null){return""}return substitute.toString()}))}getSubstitutedStringPieces(label,...args){const pieces=(label.match(/(\$[1-9])|(([^$]|\$([^1-9]|$))+)/g)||[]).map((function(p){if(!p.match(/^\$[1-9]$/)){assert((p.match(/\$/g)||[]).length%2===0,"Unescaped $ found in localized string.");return{value:p.replace(/\$\$/g,"$"),arg:null}}const substitute=args[Number(p[1])-1];if(substitute===undefined||substitute===null){return{value:"",arg:p}}return{value:substitute.toString(),arg:p}}));return pieces}getBoolean(id){const value=this.getValue(id);assert(typeof value==="boolean",`[${value}] (${id}) is not a boolean`);return value}getInteger(id){const value=this.getValue(id);assert(typeof value==="number",`[${value}] (${id}) is not a number`);assert(value===Math.floor(value),"Number isn't integer: "+value);return value}overrideValues(replacements){assert(typeof replacements==="object","Replacements must be a dictionary object.");assert(this.data_,"Data must exist before being overridden");for(const key in replacements){this.data_[key]=replacements[key]}}resetForTesting(newData=null){this.data_=newData}isInitialized(){return this.data_!==null}}const loadTimeData=new LoadTimeData;
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
function getRequiredElement(id){const el=document.querySelector(`#${id}`);assert(el);assert(el instanceof HTMLElement);return el}
/**
 * @license
 * Copyright 2019 Google LLC
 * SPDX-License-Identifier: BSD-3-Clause
 */const t$3=globalThis,e$3=t$3.ShadowRoot&&(void 0===t$3.ShadyCSS||t$3.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,s$3=Symbol(),o$4=new WeakMap;let n$3=class n{constructor(t,e,o){if(this._$cssResult$=!0,o!==s$3)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=t,this.t=e}get styleSheet(){let t=this.o;const s=this.t;if(e$3&&void 0===t){const e=void 0!==s&&1===s.length;e&&(t=o$4.get(s)),void 0===t&&((this.o=t=new CSSStyleSheet).replaceSync(this.cssText),e&&o$4.set(s,t))}return t}toString(){return this.cssText}};const r$3=t=>new n$3("string"==typeof t?t:t+"",void 0,s$3),S$1=(s,o)=>{if(e$3)s.adoptedStyleSheets=o.map((t=>t instanceof CSSStyleSheet?t:t.styleSheet));else for(const e of o){const o=document.createElement("style"),n=t$3.litNonce;void 0!==n&&o.setAttribute("nonce",n),o.textContent=e.cssText,s.appendChild(o)}},c$3=e$3?t=>t:t=>t instanceof CSSStyleSheet?(t=>{let e="";for(const s of t.cssRules)e+=s.cssText;return r$3(e)})(t):t
/**
 * @license
 * Copyright 2017 Google LLC
 * SPDX-License-Identifier: BSD-3-Clause
 */;const{is:i$3,defineProperty:e$2,getOwnPropertyDescriptor:h$2,getOwnPropertyNames:r$2,getOwnPropertySymbols:o$3,getPrototypeOf:n$2}=Object,a$1=globalThis,c$2=a$1.trustedTypes,l$1=c$2?c$2.emptyScript:"",p$1=a$1.reactiveElementPolyfillSupport,d$1=(t,s)=>t,u$1={toAttribute(t,s){switch(s){case Boolean:t=t?l$1:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t)}return t},fromAttribute(t,s){let i=t;switch(s){case Boolean:i=null!==t;break;case Number:i=null===t?null:Number(t);break;case Object:case Array:try{i=JSON.parse(t)}catch(t){i=null}}return i}},f$3=(t,s)=>!i$3(t,s),b={attribute:!0,type:String,converter:u$1,reflect:!1,useDefault:!1,hasChanged:f$3};Symbol.metadata??=Symbol("metadata"),a$1.litPropertyMetadata??=new WeakMap;let y$1=class y extends HTMLElement{static addInitializer(t){this._$Ei(),(this.l??=[]).push(t)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(t,s=b){if(s.state&&(s.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(t)&&((s=Object.create(s)).wrapped=!0),this.elementProperties.set(t,s),!s.noAccessor){const i=Symbol(),h=this.getPropertyDescriptor(t,i,s);void 0!==h&&e$2(this.prototype,t,h)}}static getPropertyDescriptor(t,s,i){const{get:e,set:r}=h$2(this.prototype,t)??{get(){return this[s]},set(t){this[s]=t}};return{get:e,set(s){const h=e?.call(this);r?.call(this,s),this.requestUpdate(t,h,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)??b}static _$Ei(){if(this.hasOwnProperty(d$1("elementProperties")))return;const t=n$2(this);t.finalize(),void 0!==t.l&&(this.l=[...t.l]),this.elementProperties=new Map(t.elementProperties)}static finalize(){if(this.hasOwnProperty(d$1("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(d$1("properties"))){const t=this.properties,s=[...r$2(t),...o$3(t)];for(const i of s)this.createProperty(i,t[i])}const t=this[Symbol.metadata];if(null!==t){const s=litPropertyMetadata.get(t);if(void 0!==s)for(const[t,i]of s)this.elementProperties.set(t,i)}this._$Eh=new Map;for(const[t,s]of this.elementProperties){const i=this._$Eu(t,s);void 0!==i&&this._$Eh.set(i,t)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(s){const i=[];if(Array.isArray(s)){const e=new Set(s.flat(1/0).reverse());for(const s of e)i.unshift(c$3(s))}else void 0!==s&&i.push(c$3(s));return i}static _$Eu(t,s){const i=s.attribute;return!1===i?void 0:"string"==typeof i?i:"string"==typeof t?t.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise((t=>this.enableUpdating=t)),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach((t=>t(this)))}addController(t){(this._$EO??=new Set).add(t),void 0!==this.renderRoot&&this.isConnected&&t.hostConnected?.()}removeController(t){this._$EO?.delete(t)}_$E_(){const t=new Map,s=this.constructor.elementProperties;for(const i of s.keys())this.hasOwnProperty(i)&&(t.set(i,this[i]),delete this[i]);t.size>0&&(this._$Ep=t)}createRenderRoot(){const t=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return S$1(t,this.constructor.elementStyles),t}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach((t=>t.hostConnected?.()))}enableUpdating(t){}disconnectedCallback(){this._$EO?.forEach((t=>t.hostDisconnected?.()))}attributeChangedCallback(t,s,i){this._$AK(t,i)}_$ET(t,s){const i=this.constructor.elementProperties.get(t),e=this.constructor._$Eu(t,i);if(void 0!==e&&!0===i.reflect){const h=(void 0!==i.converter?.toAttribute?i.converter:u$1).toAttribute(s,i.type);this._$Em=t,null==h?this.removeAttribute(e):this.setAttribute(e,h),this._$Em=null}}_$AK(t,s){const i=this.constructor,e=i._$Eh.get(t);if(void 0!==e&&this._$Em!==e){const t=i.getPropertyOptions(e),h="function"==typeof t.converter?{fromAttribute:t.converter}:void 0!==t.converter?.fromAttribute?t.converter:u$1;this._$Em=e,this[e]=h.fromAttribute(s,t.type)??this._$Ej?.get(e)??null,this._$Em=null}}requestUpdate(t,s,i){if(void 0!==t){const e=this.constructor,h=this[t];if(i??=e.getPropertyOptions(t),!((i.hasChanged??f$3)(h,s)||i.useDefault&&i.reflect&&h===this._$Ej?.get(t)&&!this.hasAttribute(e._$Eu(t,i))))return;this.C(t,s,i)}!1===this.isUpdatePending&&(this._$ES=this._$EP())}C(t,s,{useDefault:i,reflect:e,wrapped:h},r){i&&!(this._$Ej??=new Map).has(t)&&(this._$Ej.set(t,r??s??this[t]),!0!==h||void 0!==r)||(this._$AL.has(t)||(this.hasUpdated||i||(s=void 0),this._$AL.set(t,s)),!0===e&&this._$Em!==t&&(this._$Eq??=new Set).add(t))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(t){Promise.reject(t)}const t=this.scheduleUpdate();return null!=t&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[t,s]of this._$Ep)this[t]=s;this._$Ep=void 0}const t=this.constructor.elementProperties;if(t.size>0)for(const[s,i]of t){const{wrapped:t}=i,e=this[s];!0!==t||this._$AL.has(s)||void 0===e||this.C(s,void 0,i,e)}}let t=!1;const s=this._$AL;try{t=this.shouldUpdate(s),t?(this.willUpdate(s),this._$EO?.forEach((t=>t.hostUpdate?.())),this.update(s)):this._$EM()}catch(s){throw t=!1,this._$EM(),s}t&&this._$AE(s)}willUpdate(t){}_$AE(t){this._$EO?.forEach((t=>t.hostUpdated?.())),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(t){return!0}update(t){this._$Eq&&=this._$Eq.forEach((t=>this._$ET(t,this[t]))),this._$EM()}updated(t){}firstUpdated(t){}};y$1.elementStyles=[],y$1.shadowRootOptions={mode:"open"},y$1[d$1("elementProperties")]=new Map,y$1[d$1("finalized")]=new Map,p$1?.({ReactiveElement:y$1}),(a$1.reactiveElementVersions??=[]).push("2.1.0");
/**
 * @license
 * Copyright 2017 Google LLC
 * SPDX-License-Identifier: BSD-3-Clause
 */const t$2=globalThis,i$2=t$2.trustedTypes,s$2=i$2?i$2.createPolicy("lit-html-desktop",{createHTML:t=>t}):void 0,e$1="$lit$",h$1=`lit$${Math.random().toFixed(9).slice(2)}$`,o$2="?"+h$1,n$1=`<${o$2}>`,r$1=document,l=()=>r$1.createComment(""),c$1=t=>null===t||"object"!=typeof t&&"function"!=typeof t,a=Array.isArray,u=t=>a(t)||"function"==typeof t?.[Symbol.iterator],d="[ \t\n\f\r]",f$2=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,v=/-->/g,_=/>/g,m=RegExp(`>|${d}(?:([^\\s"'>=/]+)(${d}*=${d}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),p=/'/g,g=/"/g,$=/^(?:script|style|textarea|title)$/i,y=t=>(i,...s)=>({_$litType$:t,strings:i,values:s}),x=y(1),T=Symbol.for("lit-noChange"),E=Symbol.for("lit-nothing"),A=new WeakMap,C=r$1.createTreeWalker(r$1,129);function P(t,i){if(!a(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==s$2?s$2.createHTML(i):i}const V=(t,i)=>{const s=t.length-1,o=[];let r,l=2===i?"<svg>":3===i?"<math>":"",c=f$2;for(let i=0;i<s;i++){const s=t[i];let a,u,d=-1,y=0;for(;y<s.length&&(c.lastIndex=y,u=c.exec(s),null!==u);)y=c.lastIndex,c===f$2?"!--"===u[1]?c=v:void 0!==u[1]?c=_:void 0!==u[2]?($.test(u[2])&&(r=RegExp("</"+u[2],"g")),c=m):void 0!==u[3]&&(c=m):c===m?">"===u[0]?(c=r??f$2,d=-1):void 0===u[1]?d=-2:(d=c.lastIndex-u[2].length,a=u[1],c=void 0===u[3]?m:'"'===u[3]?g:p):c===g||c===p?c=m:c===v||c===_?c=f$2:(c=m,r=void 0);const x=c===m&&t[i+1].startsWith("/>")?" ":"";l+=c===f$2?s+n$1:d>=0?(o.push(a),s.slice(0,d)+e$1+s.slice(d)+h$1+x):s+h$1+(-2===d?i:x)}return[P(t,l+(t[s]||"<?>")+(2===i?"</svg>":3===i?"</math>":"")),o]};class N{constructor({strings:t,_$litType$:s},n){let r;this.parts=[];let c=0,a=0;const u=t.length-1,d=this.parts,[f,v]=V(t,s);if(this.el=N.createElement(f,n),C.currentNode=this.el.content,2===s||3===s){const t=this.el.content.firstChild;t.replaceWith(...t.childNodes)}for(;null!==(r=C.nextNode())&&d.length<u;){if(1===r.nodeType){if(r.hasAttributes())for(const t of r.getAttributeNames())if(t.endsWith(e$1)){const i=v[a++],s=r.getAttribute(t).split(h$1),e=/([.?@])?(.*)/.exec(i);d.push({type:1,index:c,name:e[2],strings:s,ctor:"."===e[1]?H:"?"===e[1]?I:"@"===e[1]?L:k}),r.removeAttribute(t)}else t.startsWith(h$1)&&(d.push({type:6,index:c}),r.removeAttribute(t));if($.test(r.tagName)){const t=r.textContent.split(h$1),s=t.length-1;if(s>0){r.textContent=i$2?i$2.emptyScript:"";for(let i=0;i<s;i++)r.append(t[i],l()),C.nextNode(),d.push({type:2,index:++c});r.append(t[s],l())}}}else if(8===r.nodeType)if(r.data===o$2)d.push({type:2,index:c});else{let t=-1;for(;-1!==(t=r.data.indexOf(h$1,t+1));)d.push({type:7,index:c}),t+=h$1.length-1}c++}}static createElement(t,i){const s=r$1.createElement("template");return s.innerHTML=t,s}}function S(t,i,s=t,e){if(i===T)return i;let h=void 0!==e?s._$Co?.[e]:s._$Cl;const o=c$1(i)?void 0:i._$litDirective$;return h?.constructor!==o&&(h?._$AO?.(!1),void 0===o?h=void 0:(h=new o(t),h._$AT(t,s,e)),void 0!==e?(s._$Co??=[])[e]=h:s._$Cl=h),void 0!==h&&(i=S(t,h._$AS(t,i.values),h,e)),i}class M{constructor(t,i){this._$AV=[],this._$AN=void 0,this._$AD=t,this._$AM=i}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(t){const{el:{content:i},parts:s}=this._$AD,e=(t?.creationScope??r$1).importNode(i,!0);C.currentNode=e;let h=C.nextNode(),o=0,n=0,l=s[0];for(;void 0!==l;){if(o===l.index){let i;2===l.type?i=new R(h,h.nextSibling,this,t):1===l.type?i=new l.ctor(h,l.name,l.strings,this,t):6===l.type&&(i=new z(h,this,t)),this._$AV.push(i),l=s[++n]}o!==l?.index&&(h=C.nextNode(),o++)}return C.currentNode=r$1,e}p(t){let i=0;for(const s of this._$AV)void 0!==s&&(void 0!==s.strings?(s._$AI(t,s,i),i+=s.strings.length-2):s._$AI(t[i])),i++}}class R{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(t,i,s,e){this.type=2,this._$AH=E,this._$AN=void 0,this._$AA=t,this._$AB=i,this._$AM=s,this.options=e,this._$Cv=e?.isConnected??!0}get parentNode(){let t=this._$AA.parentNode;const i=this._$AM;return void 0!==i&&11===t?.nodeType&&(t=i.parentNode),t}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(t,i=this){t=S(this,t,i),c$1(t)?t===E||null==t||""===t?(this._$AH!==E&&this._$AR(),this._$AH=E):t!==this._$AH&&t!==T&&this._(t):void 0!==t._$litType$?this.$(t):void 0!==t.nodeType?this.T(t):u(t)?this.k(t):this._(t)}O(t){return this._$AA.parentNode.insertBefore(t,this._$AB)}T(t){this._$AH!==t&&(this._$AR(),this._$AH=this.O(t))}_(t){this._$AH!==E&&c$1(this._$AH)?this._$AA.nextSibling.data=t:this.T(r$1.createTextNode(t)),this._$AH=t}$(t){const{values:i,_$litType$:s}=t,e="number"==typeof s?this._$AC(t):(void 0===s.el&&(s.el=N.createElement(P(s.h,s.h[0]),this.options)),s);if(this._$AH?._$AD===e)this._$AH.p(i);else{const t=new M(e,this),s=t.u(this.options);t.p(i),this.T(s),this._$AH=t}}_$AC(t){let i=A.get(t.strings);return void 0===i&&A.set(t.strings,i=new N(t)),i}k(t){a(this._$AH)||(this._$AH=[],this._$AR());const i=this._$AH;let s,e=0;for(const h of t)e===i.length?i.push(s=new R(this.O(l()),this.O(l()),this,this.options)):s=i[e],s._$AI(h),e++;e<i.length&&(this._$AR(s&&s._$AB.nextSibling,e),i.length=e)}_$AR(t=this._$AA.nextSibling,i){for(this._$AP?.(!1,!0,i);t&&t!==this._$AB;){const i=t.nextSibling;t.remove(),t=i}}setConnected(t){void 0===this._$AM&&(this._$Cv=t,this._$AP?.(t))}}class k{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(t,i,s,e,h){this.type=1,this._$AH=E,this._$AN=void 0,this.element=t,this.name=i,this._$AM=e,this.options=h,s.length>2||""!==s[0]||""!==s[1]?(this._$AH=Array(s.length-1).fill(new String),this.strings=s):this._$AH=E}_$AI(t,i=this,s,e){const h=this.strings;let o=!1;if(void 0===h)t=S(this,t,i,0),o=!c$1(t)||t!==this._$AH&&t!==T,o&&(this._$AH=t);else{const e=t;let n,r;for(t=h[0],n=0;n<h.length-1;n++)r=S(this,e[s+n],i,n),r===T&&(r=this._$AH[n]),o||=!c$1(r)||r!==this._$AH[n],r===E?t=E:t!==E&&(t+=(r??"")+h[n+1]),this._$AH[n]=r}o&&!e&&this.j(t)}j(t){t===E?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,t??"")}}class H extends k{constructor(){super(...arguments),this.type=3}j(t){this.element[this.name]=t===E?void 0:t}}class I extends k{constructor(){super(...arguments),this.type=4}j(t){this.element.toggleAttribute(this.name,!!t&&t!==E)}}class L extends k{constructor(t,i,s,e,h){super(t,i,s,e,h),this.type=5}_$AI(t,i=this){if((t=S(this,t,i,0)??E)===T)return;const s=this._$AH,e=t===E&&s!==E||t.capture!==s.capture||t.once!==s.once||t.passive!==s.passive,h=t!==E&&(s===E||e);e&&this.element.removeEventListener(this.name,this,s),h&&this.element.addEventListener(this.name,this,t),this._$AH=t}handleEvent(t){"function"==typeof this._$AH?this._$AH.call(this.options?.host??this.element,t):this._$AH.handleEvent(t)}}class z{constructor(t,i,s){this.element=t,this.type=6,this._$AN=void 0,this._$AM=i,this.options=s}get _$AU(){return this._$AM._$AU}_$AI(t){S(this,t)}}const j=t$2.litHtmlPolyfillSupport;j?.(N,R),(t$2.litHtmlVersions??=[]).push("3.3.0");const B=(t,i,s)=>{const e=s?.renderBefore??i;let h=e._$litPart$;if(void 0===h){const t=s?.renderBefore??null;e._$litPart$=h=new R(i.insertBefore(l(),t),t,void 0,s??{})}return h._$AI(t),h
/**
 * @license
 * Copyright 2017 Google LLC
 * SPDX-License-Identifier: BSD-3-Clause
 */};const s$1=globalThis;let i$1=class i extends y$1{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const t=super.createRenderRoot();return this.renderOptions.renderBefore??=t.firstChild,t}update(t){const r=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Do=B(r,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return T}};i$1._$litElement$=!0,i$1["finalized"]=!0,s$1.litElementHydrateSupport?.({LitElement:i$1});const o$1=s$1.litElementPolyfillSupport;o$1?.({LitElement:i$1});(s$1.litElementVersions??=[]).push("4.2.0");
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const HIDDEN_CLASS="hidden";
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const IS_IOS=/CriOS/.test(window.navigator.userAgent);const IS_HIDPI=window.devicePixelRatio>1;const IS_MOBILE=/Android/.test(window.navigator.userAgent)||IS_IOS;const IS_RTL=document.documentElement.dir==="rtl";const FPS=60;
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
function getRandomNum(min,max){return Math.floor(Math.random()*(max-min+1))+min}function getTimeStamp(){return IS_IOS?(new Date).getTime():performance.now()}function getRunnerImageSprite(){if("imageSprite"in Runner){return Runner.imageSprite}return null}function getRunnerAltGameImageSprite(){if("altGameImageSprite"in Runner){return Runner.altGameImageSprite}return null}function getRunnerAltCommonImageSprite(){if("altCommonImageSprite"in Runner){return Runner.altCommonImageSprite}return null}function getRunnerOrigImageSprite(){if("origImageSprite"in Runner){return Runner.origImageSprite}return null}function getRunnerSlowdown(){if("slowDown"in Runner&&typeof Runner.slowDown==="boolean"){return Runner.slowDown}return null}function getRunnerAudioCues(){if("audioCues"in Runner&&typeof Runner.audioCues==="boolean"){return Runner.audioCues}return null}function getRunnerSpriteDefinition(){if("spriteDefinition"in Runner){return Runner.spriteDefinition}return null}function getRunnerDefaultDimensions(){if("defaultDimensions"in Runner){return Runner.defaultDimensions}return null}function getRunnerConfigValue(key){if("config"in Runner&&Runner.config&&key in Runner.config){return Runner.config[key]}return null}function getRunnerGeneratedSoundFx(){if("generatedSoundFx"in Runner){return Runner.generatedSoundFx}return null}function isRunnerAltGameModeEnabled(){if("altGameModeEnabled"in Runner&&typeof Runner.altGameModeEnabled==="boolean"){return Runner.altGameModeEnabled}return null}
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var Dimensions;(function(Dimensions){Dimensions[Dimensions["WIDTH"]=10]="WIDTH";Dimensions[Dimensions["HEIGHT"]=13]="HEIGHT";Dimensions[Dimensions["DEST_WIDTH"]=11]="DEST_WIDTH"})(Dimensions||(Dimensions={}));var Config$2;(function(Config){Config[Config["MAX_DISTANCE_UNITS"]=5]="MAX_DISTANCE_UNITS";Config[Config["ACHIEVEMENT_DISTANCE"]=100]="ACHIEVEMENT_DISTANCE";Config[Config["COEFFICIENT"]=.025]="COEFFICIENT";Config[Config["FLASH_DURATION"]=250]="FLASH_DURATION";Config[Config["FLASH_ITERATIONS"]=3]="FLASH_ITERATIONS";Config[Config["HIGH_SCORE_HIT_AREA_PADDING"]=4]="HIGH_SCORE_HIT_AREA_PADDING"})(Config$2||(Config$2={}));class DistanceMeter{achievement=false;canvas;canvasCtx;image;spritePos;x=0;y=5;maxScore=0;highScore="0";digits=[];defaultString="";flashTimer=0;flashIterations=0;flashingRafId=null;highScoreBounds=null;highScoreFlashing=false;maxScoreUnits=Config$2.MAX_DISTANCE_UNITS;canvasWidth;frameTimeStamp;constructor(canvas,spritePos,canvasWidth){this.canvas=canvas;const canvasContext=canvas.getContext("2d");assert(canvasContext);this.canvasCtx=canvasContext;const runnerImageSprite=getRunnerImageSprite();assert(runnerImageSprite);this.image=runnerImageSprite;this.spritePos=spritePos;this.canvasWidth=canvasWidth;this.init(canvasWidth)}init(width){let maxDistanceStr="";this.calcXpos(width);this.maxScore=this.maxScoreUnits;for(let i=0;i<this.maxScoreUnits;i++){this.draw(i,0);this.defaultString+="0";maxDistanceStr+="9"}this.maxScore=parseInt(maxDistanceStr,10)}calcXpos(canvasWidth){this.x=canvasWidth-Dimensions.DEST_WIDTH*(this.maxScoreUnits+1)}draw(digitPos,value,highScore){let sourceWidth=Dimensions.WIDTH;let sourceHeight=Dimensions.HEIGHT;let sourceX=Dimensions.WIDTH*value;let sourceY=0;const targetX=digitPos*Dimensions.DEST_WIDTH;const targetY=this.y;const targetWidth=Dimensions.WIDTH;const targetHeight=Dimensions.HEIGHT;if(IS_HIDPI){sourceWidth*=2;sourceHeight*=2;sourceX*=2}sourceX+=this.spritePos.x;sourceY+=this.spritePos.y;this.canvasCtx.save();if(IS_RTL){const translateX=highScore?this.canvasWidth-Dimensions.WIDTH*(this.maxScoreUnits+3):this.canvasWidth-Dimensions.WIDTH;this.canvasCtx.translate(translateX,this.y);this.canvasCtx.scale(-1,1)}else{const highScoreX=this.x-this.maxScoreUnits*2*Dimensions.WIDTH;this.canvasCtx.translate(highScore?highScoreX:this.x,this.y)}this.canvasCtx.drawImage(this.image,sourceX,sourceY,sourceWidth,sourceHeight,targetX,targetY,targetWidth,targetHeight);this.canvasCtx.restore()}getActualDistance(distance){return distance?Math.round(distance*Config$2.COEFFICIENT):0}update(deltaTime,distance){let paint=true;let playSound=false;if(!this.achievement){distance=this.getActualDistance(distance);if(distance>this.maxScore&&this.maxScoreUnits===Config$2.MAX_DISTANCE_UNITS){this.maxScoreUnits++;this.maxScore=parseInt(this.maxScore+"9",10)}if(distance>0){if(distance%Config$2.ACHIEVEMENT_DISTANCE===0){this.achievement=true;this.flashTimer=0;playSound=true}const distanceStr=(this.defaultString+distance).substr(-this.maxScoreUnits);this.digits=distanceStr.split("")}else{this.digits=this.defaultString.split("")}}else{if(this.flashIterations<=Config$2.FLASH_ITERATIONS){this.flashTimer+=deltaTime;if(this.flashTimer<Config$2.FLASH_DURATION){paint=false}else if(this.flashTimer>Config$2.FLASH_DURATION*2){this.flashTimer=0;this.flashIterations++}}else{this.achievement=false;this.flashIterations=0;this.flashTimer=0}}if(paint){for(let i=this.digits.length-1;i>=0;i--){this.draw(i,parseInt(this.digits[i],10))}}this.drawHighScore();return playSound}drawHighScore(){if(this.highScore.length>0){this.canvasCtx.save();this.canvasCtx.globalAlpha=.8;for(let i=this.highScore.length-1;i>=0;i--){const characterToDraw=this.highScore[i];let characterSpritePosition=parseInt(characterToDraw,10);if(isNaN(characterSpritePosition)){switch(characterToDraw){case"H":characterSpritePosition=10;break;case"I":characterSpritePosition=11;break;default:continue}}this.draw(i,characterSpritePosition,true)}this.canvasCtx.restore()}}setHighScore(distance){distance=this.getActualDistance(distance);const highScoreStr=(this.defaultString+distance).substr(-this.maxScoreUnits);this.highScore="HI "+highScoreStr}hasClickedOnHighScore(e){let x=0;let y=0;if(e instanceof TouchEvent){const canvasBounds=this.canvas.getBoundingClientRect();x=e.touches[0].clientX-canvasBounds.left;y=e.touches[0].clientY-canvasBounds.top}else{x=e.offsetX;y=e.offsetY}this.highScoreBounds=this.getHighScoreBounds();return x>=this.highScoreBounds.x&&x<=this.highScoreBounds.x+this.highScoreBounds.width&&y>=this.highScoreBounds.y&&y<=this.highScoreBounds.y+this.highScoreBounds.height}getHighScoreBounds(){return{x:this.x-this.maxScoreUnits*2*Dimensions.WIDTH-Config$2.HIGH_SCORE_HIT_AREA_PADDING,y:this.y,width:Dimensions.WIDTH*(this.highScore.length+1)+Config$2.HIGH_SCORE_HIT_AREA_PADDING,height:Dimensions.HEIGHT+Config$2.HIGH_SCORE_HIT_AREA_PADDING*2}}flashHighScore(){const now=getTimeStamp();const deltaTime=now-(this.frameTimeStamp||now);let paint=true;this.frameTimeStamp=now;if(this.flashIterations>Config$2.FLASH_ITERATIONS*2){this.cancelHighScoreFlashing();return}this.flashTimer+=deltaTime;if(this.flashTimer<Config$2.FLASH_DURATION){paint=false}else if(this.flashTimer>Config$2.FLASH_DURATION*2){this.flashTimer=0;this.flashIterations++}if(paint){this.drawHighScore()}else{this.clearHighScoreBounds()}this.flashingRafId=requestAnimationFrame(this.flashHighScore.bind(this))}clearHighScoreBounds(){assert(this.highScoreBounds);this.canvasCtx.save();this.canvasCtx.fillStyle="#fff";this.canvasCtx.rect(this.highScoreBounds.x,this.highScoreBounds.y,this.highScoreBounds.width,this.highScoreBounds.height);this.canvasCtx.fill();this.canvasCtx.restore()}startHighScoreFlashing(){this.highScoreFlashing=true;this.flashHighScore()}isHighScoreFlashing(){return this.highScoreFlashing}cancelHighScoreFlashing(){if(this.flashingRafId){cancelAnimationFrame(this.flashingRafId)}this.flashIterations=0;this.flashTimer=0;this.highScoreFlashing=false;this.clearHighScoreBounds();this.drawHighScore()}resetHighScore(){this.setHighScore(0);this.cancelHighScoreFlashing()}reset(){this.update(0,0);this.achievement=false}}
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const GAME_TYPE=[];class CollisionBox{x;y;width;height;constructor(x,y,width,height){this.x=x;this.y=y;this.width=width;this.height=height}}const spriteDefinitionByType={original:{ldpi:{backgroundEl:{x:86,y:2},cactusLarge:{x:332,y:2},cactusSmall:{x:228,y:2},obstacle2:{x:332,y:2},obstacle:{x:228,y:2},cloud:{x:86,y:2},horizon:{x:2,y:54},moon:{x:484,y:2},pterodactyl:{x:134,y:2},restart:{x:2,y:68},textSprite:{x:655,y:2},tRex:{x:848,y:2},star:{x:645,y:2},collectable:{x:0,y:0},altGameEnd:{x:32,y:0}},hdpi:{backgroundEl:{x:166,y:2},cactusLarge:{x:652,y:2},cactusSmall:{x:446,y:2},obstacle2:{x:652,y:2},obstacle:{x:446,y:2},cloud:{x:166,y:2},horizon:{x:2,y:104},moon:{x:954,y:2},pterodactyl:{x:260,y:2},restart:{x:2,y:130},textSprite:{x:1294,y:2},tRex:{x:1678,y:2},star:{x:1276,y:2},collectable:{x:0,y:0},altGameEnd:{x:64,y:0}},maxGapCoefficient:1.5,maxObstacleLength:3,hasClouds:true,bottomPad:10,obstacles:[{type:"cactusSmall",width:17,height:35,yPos:105,multipleSpeed:4,minGap:120,minSpeed:0,collisionBoxes:[{x:0,y:7,width:5,height:27},{x:4,y:0,width:6,height:34},{x:10,y:4,width:7,height:14}]},{type:"cactusLarge",width:25,height:50,yPos:90,multipleSpeed:7,minGap:120,minSpeed:0,collisionBoxes:[{x:0,y:12,width:7,height:38},{x:8,y:0,width:7,height:49},{x:13,y:10,width:10,height:38}]},{type:"pterodactyl",width:46,height:40,yPos:[100,75,50],yPosMobile:[100,50],multipleSpeed:999,minSpeed:8.5,minGap:150,collisionBoxes:[{x:15,y:15,width:16,height:5},{x:18,y:21,width:24,height:6},{x:2,y:14,width:4,height:3},{x:6,y:10,width:4,height:7},{x:10,y:8,width:6,height:9}],numFrames:2,frameRate:1e3/6,speedOffset:.8},{type:"collectable",width:31,height:24,yPos:104,multipleSpeed:1e3,minGap:9999,minSpeed:0,collisionBoxes:[{x:0,y:0,width:32,height:25}]}],backgroundEl:{CLOUD:{height:14,offset:4,width:46,xPos:1,fixed:false}},backgroundElConfig:{maxBgEls:1,maxGap:400,minGap:100,pos:0,speed:.5,yPos:125},lines:[{sourceX:2,sourceY:52,width:600,height:12,yPos:127}],altGameOverTextConfig:{textX:32,textY:0,textWidth:246,textHeight:17,flashDuration:1500,flashing:false}}};
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const RESTART_ANIM_DURATION=875;const LOGO_PAUSE_DURATION=875;const FLASH_ITERATIONS=5;const animConfig={frames:[0,36,72,108,144,180,216,252],msPerFrame:RESTART_ANIM_DURATION/8};const defaultPanelDimensions={textX:0,textY:13,textWidth:191,textHeight:11,restartWidth:36,restartHeight:32};class GameOverPanel{canvasCtx;canvasDimensions;textImgPos;restartImgPos;altGameEndImgPos;altGameModeActive;frameTimeStamp=0;animTimer=0;currentFrame=0;gameOverRafId=null;flashTimer=0;flashCounter=0;originalText=true;constructor(canvas,textImgPos,restartImgPos,dimensions,altGameEndImgPos,altGameActive){const canvasContext=canvas.getContext("2d");assert(canvasContext);this.canvasCtx=canvasContext;this.canvasDimensions=dimensions;this.textImgPos=textImgPos;this.restartImgPos=restartImgPos;this.altGameEndImgPos=altGameEndImgPos??null;this.altGameModeActive=altGameActive??false}updateDimensions(width,height){this.canvasDimensions.width=width;if(height){this.canvasDimensions.height=height}this.currentFrame=animConfig.frames.length-1}drawGameOverText(dimensions,useAltText){const centerX=this.canvasDimensions.width/2;let textSourceX=dimensions.textX;let textSourceY=dimensions.textY;let textSourceWidth=dimensions.textWidth;let textSourceHeight=dimensions.textHeight;const textTargetX=Math.round(centerX-dimensions.textWidth/2);const textTargetY=Math.round((this.canvasDimensions.height-25)/3);const textTargetWidth=dimensions.textWidth;const textTargetHeight=dimensions.textHeight;if(IS_HIDPI){textSourceY*=2;textSourceX*=2;textSourceWidth*=2;textSourceHeight*=2}if(!useAltText){textSourceX+=this.textImgPos.x;textSourceY+=this.textImgPos.y}const spriteSource=useAltText?getRunnerAltCommonImageSprite():getRunnerOrigImageSprite();assert(spriteSource);this.canvasCtx.save();if(IS_RTL){this.canvasCtx.translate(this.canvasDimensions.width,0);this.canvasCtx.scale(-1,1)}this.canvasCtx.drawImage(spriteSource,textSourceX,textSourceY,textSourceWidth,textSourceHeight,textTargetX,textTargetY,textTargetWidth,textTargetHeight);this.canvasCtx.restore()}drawAltGameElements(tRex){const spriteDefinition=getRunnerSpriteDefinition();assert(spriteDefinition);if(this.altGameModeActive&&spriteDefinition){assert(this.altGameEndImgPos);const altGameEndConfig=spriteDefinition.altGameEndConfig;assert(altGameEndConfig);let altGameEndSourceWidth=altGameEndConfig.width;let altGameEndSourceHeight=altGameEndConfig.height;const altGameEndTargetX=tRex.xPos+altGameEndConfig.xOffset;const altGameEndTargetY=tRex.yPos+altGameEndConfig.yOffset;if(IS_HIDPI){altGameEndSourceWidth*=2;altGameEndSourceHeight*=2}const altCommonImageSprite=getRunnerAltCommonImageSprite();assert(altCommonImageSprite);this.canvasCtx.drawImage(altCommonImageSprite,this.altGameEndImgPos.x,this.altGameEndImgPos.y,altGameEndSourceWidth,altGameEndSourceHeight,altGameEndTargetX,altGameEndTargetY,altGameEndConfig.width,altGameEndConfig.height)}}drawRestartButton(){const dimensions=defaultPanelDimensions;let framePosX=animConfig.frames[this.currentFrame];let restartSourceWidth=dimensions.restartWidth;let restartSourceHeight=dimensions.restartHeight;const restartTargetX=this.canvasDimensions.width/2-dimensions.restartHeight/2;const restartTargetY=this.canvasDimensions.height/2;if(IS_HIDPI){restartSourceWidth*=2;restartSourceHeight*=2;framePosX*=2}this.canvasCtx.save();if(IS_RTL){this.canvasCtx.translate(this.canvasDimensions.width,0);this.canvasCtx.scale(-1,1)}const origImageSprite=getRunnerOrigImageSprite();assert(origImageSprite);this.canvasCtx.drawImage(origImageSprite,this.restartImgPos.x+framePosX,this.restartImgPos.y,restartSourceWidth,restartSourceHeight,restartTargetX,restartTargetY,dimensions.restartWidth,dimensions.restartHeight);this.canvasCtx.restore()}draw(altGameModeActive,tRex){if(altGameModeActive){this.altGameModeActive=altGameModeActive}this.drawGameOverText(defaultPanelDimensions,false);this.drawRestartButton();if(tRex){this.drawAltGameElements(tRex)}this.update()}update(){const now=getTimeStamp();const deltaTime=now-(this.frameTimeStamp||now);this.frameTimeStamp=now;this.animTimer+=deltaTime;this.flashTimer+=deltaTime;if(this.currentFrame===0&&this.animTimer>LOGO_PAUSE_DURATION){this.animTimer=0;this.currentFrame++;this.drawRestartButton()}else if(this.currentFrame>0&&this.currentFrame<animConfig.frames.length){if(this.animTimer>=animConfig.msPerFrame){this.currentFrame++;this.drawRestartButton()}}else if(!this.altGameModeActive&&this.currentFrame===animConfig.frames.length){this.reset();return}if(this.altGameModeActive&&spriteDefinitionByType.original.altGameOverTextConfig){const altTextConfig=spriteDefinitionByType.original.altGameOverTextConfig;if(altTextConfig.flashing){if(this.flashCounter<FLASH_ITERATIONS&&this.flashTimer>altTextConfig.flashDuration){this.flashTimer=0;this.originalText=!this.originalText;this.clearGameOverTextBounds();if(this.originalText){this.drawGameOverText(defaultPanelDimensions,false);this.flashCounter++}else{this.drawGameOverText(altTextConfig,true)}}else if(this.flashCounter>=FLASH_ITERATIONS){this.reset();return}}else{this.clearGameOverTextBounds(altTextConfig);this.drawGameOverText(altTextConfig,true)}}this.gameOverRafId=requestAnimationFrame(this.update.bind(this))}clearGameOverTextBounds(dimensions=defaultPanelDimensions){this.canvasCtx.save();this.canvasCtx.clearRect(Math.round(this.canvasDimensions.width/2-dimensions.textWidth/2),Math.round((this.canvasDimensions.height-25)/3),dimensions.textWidth,dimensions.textHeight+4);this.canvasCtx.restore()}reset(){if(this.gameOverRafId){cancelAnimationFrame(this.gameOverRafId);this.gameOverRafId=null}this.animTimer=0;this.frameTimeStamp=0;this.currentFrame=0;this.flashTimer=0;this.flashCounter=0;this.originalText=true}}
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
class GeneratedSoundFx{constructor(){this.context=new AudioContext;if(IS_IOS){this.context.onstatechange=()=>{if(this.context.state!=="running"){this.context.resume()}};this.context.resume()}this.panner=this.context.createStereoPanner?this.context.createStereoPanner():null}context;panner=null;bgSoundIntervalId=null;stopAll(){this.cancelFootSteps()}playNote(frequency,startTime,duration,vol=.01,pan=0){const osc1=this.context.createOscillator();const osc2=this.context.createOscillator();const volume=this.context.createGain();osc1.type="triangle";osc2.type="triangle";volume.gain.value=.1;if(this.panner){this.panner.pan.value=pan;osc1.connect(volume).connect(this.panner);osc2.connect(volume).connect(this.panner);this.panner.connect(this.context.destination)}else{osc1.connect(volume);osc2.connect(volume);volume.connect(this.context.destination)}osc1.frequency.value=frequency+1;osc2.frequency.value=frequency-2;volume.gain.setValueAtTime(vol,startTime+duration-.05);volume.gain.linearRampToValueAtTime(1e-5,startTime+duration);osc1.start(startTime);osc2.start(startTime);osc1.stop(startTime+duration);osc2.stop(startTime+duration)}background(){const now=this.context.currentTime;this.playNote(493.883,now,.116);this.playNote(659.255,now+.116,.232);this.loopFootSteps()}loopFootSteps(){if(!this.bgSoundIntervalId){this.bgSoundIntervalId=setInterval((()=>{this.playNote(73.42,this.context.currentTime,.05,.16);this.playNote(69.3,this.context.currentTime+.116,.116,.16)}),280)}}cancelFootSteps(){if(this.bgSoundIntervalId){clearInterval(this.bgSoundIntervalId);this.bgSoundIntervalId=null;this.playNote(103.83,this.context.currentTime,.232,.02);this.playNote(116.54,this.context.currentTime+.116,.232,.02)}}collect(){this.cancelFootSteps();const now=this.context.currentTime;this.playNote(830.61,now,.116);this.playNote(1318.51,now+.116,.232)}jump(){const now=this.context.currentTime;this.playNote(659.25,now,.116,.3,-.6);this.playNote(880,now+.116,.232,.3,-.6)}}
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
function getSpriteConfigForType(type){if("spriteDefinition"in Runner){const spriteDefinition=Runner.spriteDefinition;if(spriteDefinition){if(spriteDefinition.backgroundEl[type]){return spriteDefinition.backgroundEl[type]}}}return null}let globalConfig={maxBgEls:0,maxGap:0,minGap:0,msPerFrame:0,pos:0,speed:0,yPos:0};function getGlobalConfig(){return globalConfig}function setGlobalConfig(config){globalConfig=config}class BackgroundEl{gap;xPos;remove=false;canvas;canvasCtx;spritePos;yPos=0;type;animTimer=0;spriteConfig;switchFrames=false;constructor(canvas,spritePos,containerWidth,type){this.canvas=canvas;const canvasContext=this.canvas.getContext("2d");assert(canvasContext);this.canvasCtx=canvasContext;this.spritePos=spritePos;this.xPos=containerWidth;this.type=type;this.gap=getRandomNum(getGlobalConfig().minGap,getGlobalConfig().maxGap);const spriteConfig=getSpriteConfigForType(this.type);assert(spriteConfig);this.spriteConfig=spriteConfig;this.init()}init(){if(this.spriteConfig.fixed){assert(this.spriteConfig.fixedXPos);this.xPos=this.spriteConfig.fixedXPos}this.yPos=getGlobalConfig().yPos-this.spriteConfig.height+this.spriteConfig.offset;this.draw()}draw(){this.canvasCtx.save();let sourceWidth=this.spriteConfig.width;let sourceHeight=this.spriteConfig.height;let sourceX=this.spriteConfig.xPos;const outputWidth=sourceWidth;const outputHeight=sourceHeight;const imageSprite=getRunnerImageSprite();assert(imageSprite);if(IS_HIDPI){sourceWidth*=2;sourceHeight*=2;sourceX*=2}this.canvasCtx.drawImage(imageSprite,sourceX,this.spritePos.y,sourceWidth,sourceHeight,this.xPos,this.yPos,outputWidth,outputHeight);this.canvasCtx.restore()}update(speed){if(!this.remove){if(this.spriteConfig.fixed){const globalConfig=getGlobalConfig();assert(globalConfig.msPerFrame);this.animTimer+=speed;if(this.animTimer>globalConfig.msPerFrame){this.animTimer=0;this.switchFrames=!this.switchFrames}if(this.spriteConfig.fixedYPos1&&this.spriteConfig.fixedYPos2){this.yPos=this.switchFrames?this.spriteConfig.fixedYPos1:this.spriteConfig.fixedYPos2}}else{this.xPos-=getGlobalConfig().speed}this.draw();if(!this.isVisible()){this.remove=true}}}isVisible(){return this.xPos+this.spriteConfig.width>0}}
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
class Cloud{gap;xPos;remove=false;yPos=0;canvasCtx;spritePos;constructor(canvas,spritePos,containerWidth){const canvasContext=canvas.getContext("2d");assert(canvasContext);this.canvasCtx=canvasContext;this.xPos=containerWidth;this.spritePos=spritePos;this.gap=getRandomNum(Config$1.MIN_CLOUD_GAP,Config$1.MAX_CLOUD_GAP);this.init()}init(){this.yPos=getRandomNum(Config$1.MAX_SKY_LEVEL,Config$1.MIN_SKY_LEVEL);this.draw()}draw(){const runnerImageSprite=getRunnerImageSprite();assert(runnerImageSprite);this.canvasCtx.save();let sourceWidth=Config$1.WIDTH;let sourceHeight=Config$1.HEIGHT;const outputWidth=sourceWidth;const outputHeight=sourceHeight;if(IS_HIDPI){sourceWidth=sourceWidth*2;sourceHeight=sourceHeight*2}this.canvasCtx.drawImage(runnerImageSprite,this.spritePos.x,this.spritePos.y,sourceWidth,sourceHeight,this.xPos,this.yPos,outputWidth,outputHeight);this.canvasCtx.restore()}update(speed){if(!this.remove){this.xPos-=Math.ceil(speed);this.draw();if(!this.isVisible()){this.remove=true}}}isVisible(){return this.xPos+Config$1.WIDTH>0}}var Config$1;(function(Config){Config[Config["HEIGHT"]=14]="HEIGHT";Config[Config["MAX_CLOUD_GAP"]=400]="MAX_CLOUD_GAP";Config[Config["MAX_SKY_LEVEL"]=30]="MAX_SKY_LEVEL";Config[Config["MIN_CLOUD_GAP"]=100]="MIN_CLOUD_GAP";Config[Config["MIN_SKY_LEVEL"]=71]="MIN_SKY_LEVEL";Config[Config["WIDTH"]=46]="WIDTH"})(Config$1||(Config$1={}));
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
class HorizonLine{canvasCtx;xPos;yPos=0;bumpThreshold=.5;sourceXPos;spritePos;sourceDimensions;dimensions;constructor(canvas,lineConfig){let sourceX=lineConfig.sourceX;let sourceY=lineConfig.sourceY;if(IS_HIDPI){sourceX*=2;sourceY*=2}this.spritePos={x:sourceX,y:sourceY};const canvasContext=canvas.getContext("2d");assert(canvasContext);this.canvasCtx=canvasContext;this.dimensions={width:lineConfig.width,height:lineConfig.height};this.sourceXPos=[this.spritePos.x,this.spritePos.x+this.dimensions.width];this.xPos=[0,this.dimensions.width];this.yPos=lineConfig.yPos;this.sourceDimensions={height:lineConfig.height,width:lineConfig.width};if(IS_HIDPI){this.sourceDimensions.width=lineConfig.width*2;this.sourceDimensions.height=lineConfig.height*2}this.draw()}getRandomType(){return Math.random()>this.bumpThreshold?this.dimensions.width:0}draw(){const runnerImageSprite=getRunnerImageSprite();assert(runnerImageSprite);this.canvasCtx.drawImage(runnerImageSprite,this.sourceXPos[0],this.spritePos.y,this.sourceDimensions.width,this.sourceDimensions.height,this.xPos[0],this.yPos,this.dimensions.width,this.dimensions.height);this.canvasCtx.drawImage(runnerImageSprite,this.sourceXPos[1],this.spritePos.y,this.sourceDimensions.width,this.sourceDimensions.height,this.xPos[1],this.yPos,this.dimensions.width,this.dimensions.height)}updatexPos(pos,increment){const line1=pos;const line2=pos===0?1:0;this.xPos[line1]-=increment;this.xPos[line2]=this.xPos[line1]+this.dimensions.width;if(this.xPos[line1]<=-this.dimensions.width){this.xPos[line1]+=this.dimensions.width*2;this.xPos[line2]=this.xPos[line1]-this.dimensions.width;this.sourceXPos[line1]=this.getRandomType()+this.spritePos.x}}update(deltaTime,speed){const increment=Math.floor(speed*(FPS/1e3)*deltaTime);this.updatexPos(this.xPos[0]<=0?0:1,increment);this.draw()}reset(){this.xPos[0]=0;this.xPos[1]=this.dimensions.width}}
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const PHASES=[140,120,100,60,40,20,0];var Config;(function(Config){Config[Config["FADE_SPEED"]=.035]="FADE_SPEED";Config[Config["HEIGHT"]=40]="HEIGHT";Config[Config["MOON_SPEED"]=.25]="MOON_SPEED";Config[Config["NUM_STARS"]=2]="NUM_STARS";Config[Config["STAR_SIZE"]=9]="STAR_SIZE";Config[Config["STAR_SPEED"]=.3]="STAR_SPEED";Config[Config["STAR_MAX_Y"]=70]="STAR_MAX_Y";Config[Config["WIDTH"]=20]="WIDTH"})(Config||(Config={}));class NightMode{spritePos;canvasCtx;xPos=0;yPos=30;currentPhase=0;opacity=0;containerWidth;stars=new Array(Config.NUM_STARS);drawStars=false;constructor(canvas,spritePos,containerWidth){this.spritePos=spritePos;const canvasContext=canvas.getContext("2d");assert(canvasContext);this.canvasCtx=canvasContext;this.containerWidth=containerWidth;this.placeStars()}update(activated){if(activated&&this.opacity===0){this.currentPhase++;if(this.currentPhase>=PHASES.length){this.currentPhase=0}}if(activated&&(this.opacity<1||this.opacity===0)){this.opacity+=Config.FADE_SPEED}else if(this.opacity>0){this.opacity-=Config.FADE_SPEED}if(this.opacity>0){this.xPos=this.updateXpos(this.xPos,Config.MOON_SPEED);if(this.drawStars){for(let i=0;i<Config.NUM_STARS;i++){const star=this.stars[i];assert(star);star.x=this.updateXpos(star.x,Config.STAR_SPEED)}}this.draw()}else{this.opacity=0;this.placeStars()}this.drawStars=true}updateXpos(currentPos,speed){if(currentPos<-Config.WIDTH){currentPos=this.containerWidth}else{currentPos-=speed}return currentPos}draw(){let moonSourceWidth=this.currentPhase===3?Config.WIDTH*2:Config.WIDTH;let moonSourceHeight=Config.HEIGHT;const currentPhaseSpritePosition=PHASES[this.currentPhase];assert(currentPhaseSpritePosition!==undefined);let moonSourceX=this.spritePos.x+currentPhaseSpritePosition;const moonOutputWidth=moonSourceWidth;let starSize=Config.STAR_SIZE;let starSourceX=spriteDefinitionByType.original.ldpi.star.x;const runnerOrigImageSprite=getRunnerOrigImageSprite();assert(runnerOrigImageSprite);if(IS_HIDPI){moonSourceWidth*=2;moonSourceHeight*=2;moonSourceX=this.spritePos.x+currentPhaseSpritePosition*2;starSize*=2;starSourceX=spriteDefinitionByType.original.hdpi.star.x}this.canvasCtx.save();this.canvasCtx.globalAlpha=this.opacity;if(this.drawStars){for(const star of this.stars){this.canvasCtx.drawImage(runnerOrigImageSprite,starSourceX,star.sourceY,starSize,starSize,Math.round(star.x),star.y,Config.STAR_SIZE,Config.STAR_SIZE)}}this.canvasCtx.drawImage(runnerOrigImageSprite,moonSourceX,this.spritePos.y,moonSourceWidth,moonSourceHeight,Math.round(this.xPos),this.yPos,moonOutputWidth,Config.HEIGHT);this.canvasCtx.globalAlpha=1;this.canvasCtx.restore()}placeStars(){const segmentSize=Math.round(this.containerWidth/Config.NUM_STARS);for(let i=0;i<Config.NUM_STARS;i++){const starPosition={x:getRandomNum(segmentSize*i,segmentSize*(i+1)),y:getRandomNum(0,Config.STAR_MAX_Y),sourceY:0};if(IS_HIDPI){starPosition.sourceY=spriteDefinitionByType.original.hdpi.star.y+Config.STAR_SIZE*2*i}else{starPosition.sourceY=spriteDefinitionByType.original.ldpi.star.y+Config.STAR_SIZE*i}this.stars[i]=starPosition}}reset(){this.currentPhase=0;this.opacity=0;this.update(false)}}
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let maxGapCoefficient=1.5;let maxObstacleLength=3;function setMaxGapCoefficient(coefficient){maxGapCoefficient=coefficient}function setMaxObstacleLength(length){maxObstacleLength=length}class Obstacle{collisionBoxes=[];followingObstacleCreated=false;gap=0;jumpAlerted=false;remove=false;size;width=0;xPos;yPos=0;canvasCtx;typeConfig;spritePos;gapCoefficient;speedOffset=0;altGameModeActive;imageSprite;currentFrame=0;timer=0;constructor(canvasCtx,type,spriteImgPos,dimensions,gapCoefficient,speed,xOffset=0,isAltGameMode=false){this.canvasCtx=canvasCtx;this.spritePos=spriteImgPos;this.typeConfig=type;this.gapCoefficient=getRunnerSlowdown()?gapCoefficient*2:gapCoefficient;this.size=getRandomNum(1,maxObstacleLength);this.xPos=dimensions.width+xOffset;this.altGameModeActive=isAltGameMode;const imageSprite=this.typeConfig.type==="collectable"?getRunnerAltCommonImageSprite():this.altGameModeActive?getRunnerAltGameImageSprite():getRunnerImageSprite();assert(imageSprite);this.imageSprite=imageSprite;this.init(speed)}init(speed){this.cloneCollisionBoxes();if(this.size>1&&this.typeConfig.multipleSpeed>speed){this.size=1}this.width=this.typeConfig.width*this.size;if(Array.isArray(this.typeConfig.yPos)){assert(Array.isArray(this.typeConfig.yPosMobile));const yPosConfig=IS_MOBILE?this.typeConfig.yPosMobile:this.typeConfig.yPos;const randomYPos=yPosConfig[getRandomNum(0,yPosConfig.length-1)];assert(randomYPos);this.yPos=randomYPos}else{this.yPos=this.typeConfig.yPos}this.draw();if(this.size>1){assert(this.collisionBoxes.length>=3);this.collisionBoxes[1].width=this.width-this.collisionBoxes[0].width-this.collisionBoxes[2].width;this.collisionBoxes[2].x=this.width-this.collisionBoxes[2].width}if(this.typeConfig.speedOffset){this.speedOffset=Math.random()>.5?this.typeConfig.speedOffset:-this.typeConfig.speedOffset}this.gap=this.getGap(this.gapCoefficient,speed);if(getRunnerAudioCues()){this.gap*=2}}draw(){let sourceWidth=this.typeConfig.width;let sourceHeight=this.typeConfig.height;if(IS_HIDPI){sourceWidth=sourceWidth*2;sourceHeight=sourceHeight*2}let sourceX=sourceWidth*this.size*(.5*(this.size-1))+this.spritePos.x;if(this.currentFrame>0){sourceX+=sourceWidth*this.currentFrame}this.canvasCtx.drawImage(this.imageSprite,sourceX,this.spritePos.y,sourceWidth*this.size,sourceHeight,this.xPos,this.yPos,this.typeConfig.width*this.size,this.typeConfig.height)}update(deltaTime,speed){if(!this.remove){if(this.typeConfig.speedOffset){speed+=this.speedOffset}this.xPos-=Math.floor(speed*FPS/1e3*deltaTime);if(this.typeConfig.numFrames){assert(this.typeConfig.frameRate);this.timer+=deltaTime;if(this.timer>=this.typeConfig.frameRate){this.currentFrame=this.currentFrame===this.typeConfig.numFrames-1?0:this.currentFrame+1;this.timer=0}}this.draw();if(!this.isVisible()){this.remove=true}}}getGap(gapCoefficient,speed){const minGap=Math.round(this.width*speed+this.typeConfig.minGap*gapCoefficient);const maxGap=Math.round(minGap*maxGapCoefficient);return getRandomNum(minGap,maxGap)}isVisible(){return this.xPos+this.width>0}cloneCollisionBoxes(){const collisionBoxes=this.typeConfig.collisionBoxes;for(let i=collisionBoxes.length-1;i>=0;i--){this.collisionBoxes[i]=new CollisionBox(collisionBoxes[i].x,collisionBoxes[i].y,collisionBoxes[i].width,collisionBoxes[i].height)}}}
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
class Horizon{canvas;canvasCtx;config=horizonConfig;dimensions;gapCoefficient;obstacles=[];obstacleHistory=[];cloudFrequency;spritePos;nightMode;altGameModeActive=false;obstacleTypes=[];clouds=[];cloudSpeed;backgroundEls=[];lastEl=null;horizonLines=[];constructor(canvas,spritePos,dimensions,gapCoefficient){this.canvas=canvas;const canvasContext=canvas.getContext("2d");assert(canvasContext);this.canvasCtx=canvasContext;this.dimensions=dimensions;this.gapCoefficient=gapCoefficient;this.cloudFrequency=this.config.CLOUD_FREQUENCY;this.spritePos=spritePos;this.cloudSpeed=this.config.BG_CLOUD_SPEED;this.obstacleTypes=spriteDefinitionByType.original.obstacles;this.addCloud();const runnerSpriteDefinition=getRunnerSpriteDefinition();assert(runnerSpriteDefinition);for(let i=0;i<runnerSpriteDefinition.lines.length;i++){this.horizonLines.push(new HorizonLine(this.canvas,runnerSpriteDefinition.lines[i]))}this.nightMode=new NightMode(this.canvas,this.spritePos.moon,this.dimensions.height)}adjustObstacleSpeed(){for(let i=0;i<this.obstacleTypes.length;i++){if(getRunnerSlowdown()){this.obstacleTypes[i].multipleSpeed=this.obstacleTypes[i].multipleSpeed/2;this.obstacleTypes[i].minGap*=1.5;this.obstacleTypes[i].minSpeed=this.obstacleTypes[i].minSpeed/2;const obstacleYpos=this.obstacleTypes[i].yPos;if(Array.isArray(obstacleYpos)&&obstacleYpos.length>1){this.obstacleTypes[i].yPos=obstacleYpos[0]}}}}enableAltGameMode(spritePos){const runnerSpriteDefinition=getRunnerSpriteDefinition();assert(runnerSpriteDefinition);this.clouds=[];this.backgroundEls=[];this.altGameModeActive=true;this.spritePos=spritePos;this.obstacleTypes=runnerSpriteDefinition.obstacles;this.adjustObstacleSpeed();setMaxGapCoefficient(runnerSpriteDefinition.maxGapCoefficient);setMaxObstacleLength(runnerSpriteDefinition.maxObstacleLength);setGlobalConfig(runnerSpriteDefinition.backgroundElConfig);this.horizonLines=[];for(let i=0;i<runnerSpriteDefinition.lines.length;i++){this.horizonLines.push(new HorizonLine(this.canvas,runnerSpriteDefinition.lines[i]))}this.reset()}update(deltaTime,currentSpeed,updateObstacles,showNightMode){const runnerSpriteDefinition=getRunnerSpriteDefinition();assert(runnerSpriteDefinition);if(this.altGameModeActive){this.updateBackgroundEls(deltaTime)}for(const line of this.horizonLines){line.update(deltaTime,currentSpeed)}if(!this.altGameModeActive||runnerSpriteDefinition.hasClouds){this.nightMode.update(showNightMode);this.updateClouds(deltaTime,currentSpeed)}if(updateObstacles){this.updateObstacles(deltaTime,currentSpeed)}}updateBackgroundEl(elSpeed,bgElArray,maxBgEl,bgElAddFunction,frequency){const numElements=bgElArray.length;if(!numElements){bgElAddFunction();return}for(let i=numElements-1;i>=0;i--){bgElArray[i].update(elSpeed)}const lastEl=bgElArray.at(-1);if(numElements<maxBgEl&&this.dimensions.width-lastEl.xPos>lastEl.gap&&frequency>Math.random()){bgElAddFunction()}}updateClouds(deltaTime,speed){const elSpeed=this.cloudSpeed/1e3*deltaTime*speed;this.updateBackgroundEl(elSpeed,this.clouds,this.config.MAX_CLOUDS,this.addCloud.bind(this),this.cloudFrequency);this.clouds=this.clouds.filter((obj=>!obj.remove))}updateBackgroundEls(deltaTime){this.updateBackgroundEl(deltaTime,this.backgroundEls,getGlobalConfig().maxBgEls,this.addBackgroundEl.bind(this),this.cloudFrequency);this.backgroundEls=this.backgroundEls.filter((obj=>!obj.remove))}updateObstacles(deltaTime,currentSpeed){const updatedObstacles=this.obstacles.slice(0);for(const obstacle of this.obstacles){obstacle.update(deltaTime,currentSpeed);if(obstacle.remove){updatedObstacles.shift()}}this.obstacles=updatedObstacles;if(this.obstacles.length>0){const lastObstacle=this.obstacles.at(-1);if(lastObstacle&&!lastObstacle.followingObstacleCreated&&lastObstacle.isVisible()&&lastObstacle.xPos+lastObstacle.width+lastObstacle.gap<this.dimensions.width){this.addNewObstacle(currentSpeed);lastObstacle.followingObstacleCreated=true}}else{this.addNewObstacle(currentSpeed)}}removeFirstObstacle(){this.obstacles.shift()}addNewObstacle(currentSpeed){const obstacleCount=this.obstacleTypes[this.obstacleTypes.length-1].type!=="collectable"||(isRunnerAltGameModeEnabled()&&!this.altGameModeActive||this.altGameModeActive)?this.obstacleTypes.length-1:this.obstacleTypes.length-2;const obstacleTypeIndex=obstacleCount>0?getRandomNum(0,obstacleCount):0;const obstacleType=this.obstacleTypes[obstacleTypeIndex];if(obstacleCount>0&&this.duplicateObstacleCheck(obstacleType.type)||currentSpeed<obstacleType.minSpeed){this.addNewObstacle(currentSpeed)}else{const obstacleSpritePos=this.spritePos[obstacleType.type];this.obstacles.push(new Obstacle(this.canvasCtx,obstacleType,obstacleSpritePos,this.dimensions,this.gapCoefficient,currentSpeed,obstacleType.width,this.altGameModeActive));this.obstacleHistory.unshift(obstacleType.type);if(this.obstacleHistory.length>1){const maxObstacleDuplicationValue=getRunnerConfigValue("MAX_OBSTACLE_DUPLICATION");assert(maxObstacleDuplicationValue);this.obstacleHistory.splice(maxObstacleDuplicationValue)}}}duplicateObstacleCheck(nextObstacleType){let duplicateCount=0;for(const obstacle of this.obstacleHistory){duplicateCount=obstacle===nextObstacleType?duplicateCount+1:0}const maxObstacleDuplicationValue=getRunnerConfigValue("MAX_OBSTACLE_DUPLICATION");assert(maxObstacleDuplicationValue);return duplicateCount>=maxObstacleDuplicationValue}reset(){this.obstacles=[];for(let l=0;l<this.horizonLines.length;l++){this.horizonLines[l].reset()}this.nightMode.reset()}resize(width,height){this.canvas.width=width;this.canvas.height=height}addCloud(){this.clouds.push(new Cloud(this.canvas,this.spritePos.cloud,this.dimensions.width))}addBackgroundEl(){const runnerSpriteDefinition=getRunnerSpriteDefinition();assert(runnerSpriteDefinition);const backgroundElTypes=Object.keys(runnerSpriteDefinition.backgroundEl);if(backgroundElTypes.length>0){let index=getRandomNum(0,backgroundElTypes.length-1);let type=backgroundElTypes[index];while(type===this.lastEl&&backgroundElTypes.length>1){index=getRandomNum(0,backgroundElTypes.length-1);type=backgroundElTypes[index]}this.lastEl=type;this.backgroundEls.push(new BackgroundEl(this.canvas,this.spritePos.backgroundEl,this.dimensions.width,type))}}}const horizonConfig={BG_CLOUD_SPEED:.2,BUMPY_THRESHOLD:.3,CLOUD_FREQUENCY:.5,HORIZON_HEIGHT:16,MAX_CLOUDS:6};
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const defaultTrexConfig={dropVelocity:-5,flashOff:175,flashOn:100,height:47,heightDuck:25,introDuration:1500,speedDropCoefficient:3,spriteWidth:262,startXPos:50,width:44,widthDuck:59,invertJump:false};const slowJumpConfig={gravity:.25,maxJumpHeight:50,minJumpHeight:45,initialJumpVelocity:-20};const normalJumpConfig={gravity:.6,maxJumpHeight:30,minJumpHeight:30,initialJumpVelocity:-10};const collisionBoxes={ducking:[new CollisionBox(1,18,55,25)],running:[new CollisionBox(22,0,17,16),new CollisionBox(1,18,30,9),new CollisionBox(10,35,14,8),new CollisionBox(1,24,29,5),new CollisionBox(5,30,21,4),new CollisionBox(9,34,15,4)]};var Status;(function(Status){Status[Status["CRASHED"]=0]="CRASHED";Status[Status["DUCKING"]=1]="DUCKING";Status[Status["JUMPING"]=2]="JUMPING";Status[Status["RUNNING"]=3]="RUNNING";Status[Status["WAITING"]=4]="WAITING"})(Status||(Status={}));const BLINK_TIMING=7e3;const animFrames={[Status.WAITING]:{frames:[44,0],msPerFrame:1e3/3},[Status.RUNNING]:{frames:[88,132],msPerFrame:1e3/12},[Status.CRASHED]:{frames:[220],msPerFrame:1e3/60},[Status.JUMPING]:{frames:[0],msPerFrame:1e3/60},[Status.DUCKING]:{frames:[264,323],msPerFrame:1e3/8}};class Trex{config;playingIntro=false;xPos=0;yPos=0;jumpCount=0;ducking=false;blinkCount=0;jumping=false;speedDrop=false;canvasCtx;spritePos;xInitialPos=0;groundYPos=0;currentFrame=0;currentAnimFrames=[];blinkDelay=0;animStartTime=0;timer=0;msPerFrame=1e3/FPS;status=Status.WAITING;jumpVelocity=0;reachedMinHeight=false;altGameModeEnabled=false;flashing=false;minJumpHeight;constructor(canvas,spritePos){const canvasContext=canvas.getContext("2d");assert(canvasContext);this.canvasCtx=canvasContext;this.spritePos=spritePos;this.config=Object.assign(defaultTrexConfig,normalJumpConfig);const runnerDefaultDimensions=getRunnerDefaultDimensions();const runnerBottomPadding=getRunnerConfigValue("BOTTOM_PAD");assert(runnerDefaultDimensions);assert(runnerBottomPadding);this.groundYPos=runnerDefaultDimensions.height-this.config.height-runnerBottomPadding;this.yPos=this.groundYPos;this.minJumpHeight=this.groundYPos-this.config.minJumpHeight;this.draw(0,0);this.update(0,Status.WAITING)}enableSlowConfig(){const jumpConfig=getRunnerSlowdown()?slowJumpConfig:normalJumpConfig;this.config=Object.assign(defaultTrexConfig,jumpConfig);this.adjustAltGameConfigForSlowSpeed()}enableAltGameMode(spritePos){this.altGameModeEnabled=true;this.spritePos=spritePos;const spriteDefinition=getRunnerSpriteDefinition();assert(spriteDefinition);const tRexSpriteDefinition=spriteDefinition.tRex;assert(tRexSpriteDefinition.running1);const runnerDefaultDimensions=getRunnerDefaultDimensions();assert(runnerDefaultDimensions);animFrames[Status.RUNNING].frames=[tRexSpriteDefinition.running1.x,tRexSpriteDefinition.running2.x];animFrames[Status.CRASHED].frames=[tRexSpriteDefinition.crashed.x];if(typeof tRexSpriteDefinition.jumping.x==="object"){animFrames[Status.JUMPING].frames=tRexSpriteDefinition.jumping.x}else{animFrames[Status.JUMPING].frames=[tRexSpriteDefinition.jumping.x]}animFrames[Status.DUCKING].frames=[tRexSpriteDefinition.ducking1.x,tRexSpriteDefinition.ducking2.x];this.config.gravity=tRexSpriteDefinition.gravity||this.config.gravity;this.config.height=tRexSpriteDefinition.running1.h,this.config.initialJumpVelocity=tRexSpriteDefinition.initialJumpVelocity;this.config.maxJumpHeight=tRexSpriteDefinition.maxJumpHeight;this.config.minJumpHeight=tRexSpriteDefinition.minJumpHeight;this.config.width=tRexSpriteDefinition.running1.w;this.config.widthCrashed=tRexSpriteDefinition.crashed.w;this.config.widthJump=tRexSpriteDefinition.jumping.w;this.config.invertJump=tRexSpriteDefinition.invertJump;this.adjustAltGameConfigForSlowSpeed(tRexSpriteDefinition.gravity);this.groundYPos=runnerDefaultDimensions.height-this.config.height-spriteDefinition.bottomPad;this.yPos=this.groundYPos;this.reset()}adjustAltGameConfigForSlowSpeed(gravityValue){if(getRunnerSlowdown()){if(gravityValue){this.config.gravity=gravityValue/1.5}this.config.minJumpHeight*=1.5;this.config.maxJumpHeight*=1.5;this.config.initialJumpVelocity*=1.5}}setFlashing(status){this.flashing=status}setJumpVelocity(setting){this.config.initialJumpVelocity=-setting;this.config.dropVelocity=-setting/2}update(deltaTime,status){this.timer+=deltaTime;if(status!==undefined){this.status=status;this.currentFrame=0;this.msPerFrame=animFrames[status].msPerFrame;this.currentAnimFrames=animFrames[status].frames;if(status===Status.WAITING){this.animStartTime=getTimeStamp();this.setBlinkDelay()}}if(this.playingIntro&&this.xPos<this.config.startXPos){this.xPos+=Math.round(this.config.startXPos/this.config.introDuration*deltaTime);this.xInitialPos=this.xPos}if(this.status===Status.WAITING){this.blink(getTimeStamp())}else{this.draw(this.currentAnimFrames[this.currentFrame],0)}if(!this.flashing&&this.timer>=this.msPerFrame){this.currentFrame=this.currentFrame===this.currentAnimFrames.length-1?0:this.currentFrame+1;this.timer=0}if(this.speedDrop&&this.yPos===this.groundYPos){this.speedDrop=false;this.setDuck(true)}}draw(x,y){let sourceX=x;let sourceY=y;let sourceWidth=this.ducking&&this.status!==Status.CRASHED?this.config.widthDuck:this.config.width;let sourceHeight=this.config.height;const outputHeight=sourceHeight;if(this.altGameModeEnabled){assert(this.config.widthCrashed)}const outputWidth=this.altGameModeEnabled&&this.status===Status.CRASHED?this.config.widthCrashed:this.config.width;const runnerImageSprite=getRunnerImageSprite();assert(runnerImageSprite);if(this.altGameModeEnabled){if(this.jumping&&this.status!==Status.CRASHED){assert(this.config.widthJump);sourceWidth=this.config.widthJump}else if(this.status===Status.CRASHED){assert(this.config.widthCrashed);sourceWidth=this.config.widthCrashed}}if(IS_HIDPI){sourceX*=2;sourceY*=2;sourceWidth*=2;sourceHeight*=2}sourceX+=this.spritePos.x;sourceY+=this.spritePos.y;if(this.flashing){if(this.timer<this.config.flashOn){this.canvasCtx.globalAlpha=.5}else if(this.timer>this.config.flashOff){this.timer=0}}if(this.ducking&&this.status!==Status.CRASHED){this.canvasCtx.drawImage(runnerImageSprite,sourceX,sourceY,sourceWidth,sourceHeight,this.xPos,this.yPos,this.config.widthDuck,outputHeight)}else if(this.altGameModeEnabled&&this.jumping&&this.status!==Status.CRASHED){assert(this.config.widthJump);const spriteDefinition=getRunnerSpriteDefinition();assert(spriteDefinition);assert(spriteDefinition.tRex);const jumpOffset=spriteDefinition.tRex.jumping.xOffset*(IS_HIDPI?2:1);this.canvasCtx.drawImage(runnerImageSprite,sourceX,sourceY,sourceWidth,sourceHeight,this.xPos-jumpOffset,this.yPos,this.config.widthJump,outputHeight)}else{if(this.ducking&&this.status===Status.CRASHED){this.xPos++}this.canvasCtx.drawImage(runnerImageSprite,sourceX,sourceY,sourceWidth,sourceHeight,this.xPos,this.yPos,outputWidth,outputHeight)}this.canvasCtx.globalAlpha=1}setBlinkDelay(){this.blinkDelay=Math.ceil(Math.random()*BLINK_TIMING)}blink(time){const deltaTime=time-this.animStartTime;if(deltaTime>=this.blinkDelay){this.draw(this.currentAnimFrames[this.currentFrame],0);if(this.currentFrame===1){this.setBlinkDelay();this.animStartTime=time;this.blinkCount++}}}startJump(speed){if(!this.jumping){this.update(0,Status.JUMPING);this.jumpVelocity=this.config.initialJumpVelocity-speed/10;this.jumping=true;this.reachedMinHeight=false;this.speedDrop=false;if(this.config.invertJump){this.minJumpHeight=this.groundYPos+this.config.minJumpHeight}}}endJump(){if(this.reachedMinHeight&&this.jumpVelocity<this.config.dropVelocity){this.jumpVelocity=this.config.dropVelocity}}updateJump(deltaTime){const msPerFrame=animFrames[this.status].msPerFrame;const framesElapsed=deltaTime/msPerFrame;if(this.speedDrop){this.yPos+=Math.round(this.jumpVelocity*this.config.speedDropCoefficient*framesElapsed)}else if(this.config.invertJump){this.yPos-=Math.round(this.jumpVelocity*framesElapsed)}else{this.yPos+=Math.round(this.jumpVelocity*framesElapsed)}this.jumpVelocity+=this.config.gravity*framesElapsed;if(this.config.invertJump&&this.yPos>this.minJumpHeight||!this.config.invertJump&&this.yPos<this.minJumpHeight||this.speedDrop){this.reachedMinHeight=true}if(this.config.invertJump&&this.yPos>-this.config.maxJumpHeight||!this.config.invertJump&&this.yPos<this.config.maxJumpHeight||this.speedDrop){this.endJump()}if(this.config.invertJump&&this.yPos<this.groundYPos||!this.config.invertJump&&this.yPos>this.groundYPos){this.reset();this.jumpCount++;if(getRunnerAudioCues()){const generatedSoundFx=getRunnerGeneratedSoundFx();assert(generatedSoundFx);generatedSoundFx.loopFootSteps()}}}setSpeedDrop(){this.speedDrop=true;this.jumpVelocity=1}setDuck(isDucking){if(isDucking&&this.status!==Status.DUCKING){this.update(0,Status.DUCKING);this.ducking=true}else if(this.status===Status.DUCKING){this.update(0,Status.RUNNING);this.ducking=false}}reset(){this.xPos=this.xInitialPos;this.yPos=this.groundYPos;this.jumpVelocity=0;this.jumping=false;this.ducking=false;this.update(0,Status.RUNNING);this.speedDrop=false;this.jumpCount=0}getCollisionBoxes(){return this.ducking?collisionBoxes.ducking:collisionBoxes.running}}
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
function Runner(outerContainerId,opt_config){if(Runner.instance_){return Runner.instance_}Runner.instance_=this;this.outerContainerEl=document.querySelector(outerContainerId);this.containerEl=null;this.snackbarEl=null;this.touchController=null;this.config=opt_config||Object.assign(Runner.config,Runner.normalConfig);this.dimensions=Runner.defaultDimensions;this.gameType=null;Runner.spriteDefinition=spriteDefinitionByType["original"];this.altGameImageSprite=null;this.altGameModeActive=false;this.altGameModeFlashTimer=null;this.fadeInTimer=0;this.canvas=null;this.canvasCtx=null;this.tRex=null;this.distanceMeter=null;this.distanceRan=0;this.highestScore=0;this.syncHighestScore=false;this.time=0;this.runningTime=0;this.msPerFrame=1e3/FPS;this.currentSpeed=this.config.SPEED;Runner.slowDown=false;this.obstacles=[];this.activated=false;this.playing=false;this.crashed=false;this.paused=false;this.inverted=false;this.invertTimer=0;this.resizeTimerId_=null;this.playCount=0;this.audioBuffer=null;this.soundFx={};this.generatedSoundFx=null;this.audioContext=null;this.images={};this.imagesLoaded=0;this.pollingGamepads=false;this.gamepadIndex=undefined;this.previousGamepad=null;if(this.isDisabled()){this.setupDisabledRunner()}else{if(Runner.isAltGameModeEnabled()){this.initAltGameType();Runner.gameType=this.gameType}this.loadImages();window["initializeEasterEggHighScore"]=this.initializeHighScore.bind(this)}}const DEFAULT_WIDTH=600;const ARCADE_MODE_URL="chrome://dino/";const RESOURCE_POSTFIX="offline-resources-";const A11Y_STRINGS={ariaLabel:"dinoGameA11yAriaLabel",description:"dinoGameA11yDescription",gameOver:"dinoGameA11yGameOver",highScore:"dinoGameA11yHighScore",jump:"dinoGameA11yJump",started:"dinoGameA11yStartGame",speedLabel:"dinoGameA11ySpeedToggle"};Runner.config={AUDIOCUE_PROXIMITY_THRESHOLD:190,AUDIOCUE_PROXIMITY_THRESHOLD_MOBILE_A11Y:250,BG_CLOUD_SPEED:.2,BOTTOM_PAD:10,CANVAS_IN_VIEW_OFFSET:-10,CLEAR_TIME:3e3,CLOUD_FREQUENCY:.5,FADE_DURATION:1,FLASH_DURATION:1e3,GAMEOVER_CLEAR_TIME:1200,INITIAL_JUMP_VELOCITY:12,INVERT_FADE_DURATION:12e3,MAX_BLINK_COUNT:3,MAX_CLOUDS:6,MAX_OBSTACLE_LENGTH:3,MAX_OBSTACLE_DUPLICATION:2,RESOURCE_TEMPLATE_ID:"audio-resources",SPEED:6,SPEED_DROP_COEFFICIENT:3,ARCADE_MODE_INITIAL_TOP_POSITION:35,ARCADE_MODE_TOP_POSITION_PERCENT:.1};Runner.normalConfig={ACCELERATION:.001,AUDIOCUE_PROXIMITY_THRESHOLD:190,AUDIOCUE_PROXIMITY_THRESHOLD_MOBILE_A11Y:250,GAP_COEFFICIENT:.6,INVERT_DISTANCE:700,MAX_SPEED:13,MOBILE_SPEED_COEFFICIENT:1.2,SPEED:6};Runner.slowConfig={ACCELERATION:5e-4,AUDIOCUE_PROXIMITY_THRESHOLD:170,AUDIOCUE_PROXIMITY_THRESHOLD_MOBILE_A11Y:220,GAP_COEFFICIENT:.3,INVERT_DISTANCE:350,MAX_SPEED:9,MOBILE_SPEED_COEFFICIENT:1.5,SPEED:4.2};Runner.defaultDimensions={width:DEFAULT_WIDTH,height:150};Runner.classes={ARCADE_MODE:"arcade-mode",CANVAS:"runner-canvas",CONTAINER:"runner-container",CRASHED:"crashed",ICON:"icon-offline",INVERTED:"inverted",SNACKBAR:"snackbar",SNACKBAR_SHOW:"snackbar-show",TOUCH_CONTROLLER:"controller"};Runner.sounds={BUTTON_PRESS:"offline-sound-press",HIT:"offline-sound-hit",SCORE:"offline-sound-reached"};Runner.keycodes={JUMP:{38:1,32:1},DUCK:{40:1},RESTART:{13:1}};Runner.events={ANIM_END:"webkitAnimationEnd",CLICK:"click",KEYDOWN:"keydown",KEYUP:"keyup",POINTERDOWN:"pointerdown",POINTERUP:"pointerup",RESIZE:"resize",TOUCHEND:"touchend",TOUCHSTART:"touchstart",VISIBILITY:"visibilitychange",BLUR:"blur",FOCUS:"focus",LOAD:"load",GAMEPADCONNECTED:"gamepadconnected"};Runner.prototype={initAltGameType(){if(GAME_TYPE.length>0){this.gameType=loadTimeData&&loadTimeData.valueExists("altGameType")?GAME_TYPE[parseInt(loadTimeData.getValue("altGameType"),10)-1]:""}},isDisabled(){return loadTimeData&&loadTimeData.valueExists("disabledEasterEgg")},setupDisabledRunner(){this.containerEl=document.createElement("div");this.containerEl.className=Runner.classes.SNACKBAR;this.containerEl.textContent=loadTimeData.getValue("disabledEasterEgg");this.outerContainerEl.appendChild(this.containerEl);document.addEventListener(Runner.events.KEYDOWN,function(e){if(Runner.keycodes.JUMP[e.keyCode]){this.containerEl.classList.add(Runner.classes.SNACKBAR_SHOW);document.querySelector(".icon").classList.add("icon-disabled")}}.bind(this))},updateConfigSetting(setting,value){if(setting in this.config&&value!==undefined){this.config[setting]=value;switch(setting){case"gravity":case"minJumpHeight":case"speedDropCoefficient":this.tRex.config[setting]=value;break;case"initialJumpVelocity":this.tRex.setJumpVelocity(value);break;case"speed":this.setSpeed(value);break}}},createImageElement(resourceName){const imgSrc=loadTimeData&&loadTimeData.valueExists(resourceName)?loadTimeData.getString(resourceName):null;if(imgSrc){const el=document.createElement("img");el.id=resourceName;el.src=imgSrc;document.getElementById("offline-resources").appendChild(el);return el}return null},loadImages(){let scale="1x";this.spriteDef=Runner.spriteDefinition.ldpi;if(IS_HIDPI){scale="2x";this.spriteDef=Runner.spriteDefinition.hdpi}Runner.imageSprite=document.getElementById(RESOURCE_POSTFIX+scale);if(this.gameType){Runner.altGameImageSprite=this.createImageElement("altGameSpecificImage"+scale);Runner.altCommonImageSprite=this.createImageElement("altGameCommonImage"+scale)}Runner.origImageSprite=Runner.imageSprite;if(!Runner.altGameImageSprite||!Runner.altCommonImageSprite){Runner.isAltGameModeEnabled=()=>false;this.altGameModeActive=false}if(Runner.imageSprite.complete){this.init()}else{Runner.imageSprite.addEventListener(Runner.events.LOAD,this.init.bind(this))}},loadSounds(){if(!IS_IOS){this.audioContext=new AudioContext;const resourceTemplate=document.getElementById(this.config.RESOURCE_TEMPLATE_ID).content;for(const sound in Runner.sounds){let soundSrc=resourceTemplate.getElementById(Runner.sounds[sound]).src;soundSrc=soundSrc.substr(soundSrc.indexOf(",")+1);const buffer=decodeBase64ToArrayBuffer(soundSrc);this.audioContext.decodeAudioData(buffer,function(index,audioData){this.soundFx[index]=audioData}.bind(this,sound))}}},setSpeed(opt_speed){const speed=opt_speed||this.currentSpeed;if(this.dimensions.width<DEFAULT_WIDTH){const mobileSpeed=Runner.slowDown?speed:speed*this.dimensions.width/DEFAULT_WIDTH*this.config.MOBILE_SPEED_COEFFICIENT;this.currentSpeed=mobileSpeed>speed?speed:mobileSpeed}else if(opt_speed){this.currentSpeed=opt_speed}},init(){document.querySelector("."+Runner.classes.ICON).style.visibility="hidden";if(this.isArcadeMode()){document.title=document.title+" - "+getA11yString(A11Y_STRINGS.ariaLabel)}this.adjustDimensions();this.setSpeed();const ariaLabel=getA11yString(A11Y_STRINGS.ariaLabel);this.containerEl=document.createElement("div");this.containerEl.setAttribute("role",IS_MOBILE?"button":"application");this.containerEl.setAttribute("tabindex","0");this.containerEl.setAttribute("title",getA11yString(A11Y_STRINGS.description));this.containerEl.setAttribute("aria-label",ariaLabel);this.containerEl.className=Runner.classes.CONTAINER;this.canvas=createCanvas(this.containerEl,this.dimensions.width,this.dimensions.height);this.a11yStatusEl=document.createElement("span");this.a11yStatusEl.className="offline-runner-live-region";this.a11yStatusEl.setAttribute("aria-live","assertive");this.a11yStatusEl.textContent="";Runner.a11yStatusEl=this.a11yStatusEl;this.slowSpeedCheckboxLabel=document.createElement("label");this.slowSpeedCheckboxLabel.className="slow-speed-option hidden";this.slowSpeedCheckboxLabel.textContent=getA11yString(A11Y_STRINGS.speedLabel);this.slowSpeedCheckbox=document.createElement("input");this.slowSpeedCheckbox.setAttribute("type","checkbox");this.slowSpeedCheckbox.setAttribute("title",getA11yString(A11Y_STRINGS.speedLabel));this.slowSpeedCheckbox.setAttribute("tabindex","0");this.slowSpeedCheckbox.setAttribute("checked","checked");this.slowSpeedToggleEl=document.createElement("span");this.slowSpeedToggleEl.className="slow-speed-toggle";this.slowSpeedCheckboxLabel.appendChild(this.slowSpeedCheckbox);this.slowSpeedCheckboxLabel.appendChild(this.slowSpeedToggleEl);if(IS_IOS){this.outerContainerEl.appendChild(this.a11yStatusEl)}else{this.containerEl.appendChild(this.a11yStatusEl)}this.canvasCtx=this.canvas.getContext("2d");this.canvasCtx.fillStyle="#f7f7f7";this.canvasCtx.fill();Runner.updateCanvasScaling(this.canvas);this.horizon=new Horizon(this.canvas,this.spriteDef,this.dimensions,this.config.GAP_COEFFICIENT);this.distanceMeter=new DistanceMeter(this.canvas,this.spriteDef.textSprite,this.dimensions.width);this.tRex=new Trex(this.canvas,this.spriteDef.tRex);this.outerContainerEl.appendChild(this.containerEl);this.outerContainerEl.appendChild(this.slowSpeedCheckboxLabel);this.startListening();this.update();window.addEventListener(Runner.events.RESIZE,this.debounceResize.bind(this));const darkModeMediaQuery=window.matchMedia("(prefers-color-scheme: dark)");this.isDarkMode=darkModeMediaQuery&&darkModeMediaQuery.matches;darkModeMediaQuery.addListener((e=>{this.isDarkMode=e.matches}))},createTouchController(){this.touchController=document.createElement("div");this.touchController.className=Runner.classes.TOUCH_CONTROLLER;this.touchController.addEventListener(Runner.events.TOUCHSTART,this);this.touchController.addEventListener(Runner.events.TOUCHEND,this);this.outerContainerEl.appendChild(this.touchController)},debounceResize(){if(!this.resizeTimerId_){this.resizeTimerId_=setInterval(this.adjustDimensions.bind(this),250)}},adjustDimensions(){clearInterval(this.resizeTimerId_);this.resizeTimerId_=null;const boxStyles=window.getComputedStyle(this.outerContainerEl);const padding=Number(boxStyles.paddingLeft.substr(0,boxStyles.paddingLeft.length-2));this.dimensions.width=this.outerContainerEl.offsetWidth-padding*2;if(this.isArcadeMode()){this.dimensions.width=Math.min(DEFAULT_WIDTH,this.dimensions.width);if(this.activated){this.setArcadeModeContainerScale()}}if(this.canvas){this.canvas.width=this.dimensions.width;this.canvas.height=this.dimensions.height;Runner.updateCanvasScaling(this.canvas);this.distanceMeter.calcXPos(this.dimensions.width);this.clearCanvas();this.horizon.update(0,0,true);this.tRex.update(0);if(this.playing||this.crashed||this.paused){this.containerEl.style.width=this.dimensions.width+"px";this.containerEl.style.height=this.dimensions.height+"px";this.distanceMeter.update(0,Math.ceil(this.distanceRan));this.stop()}else{this.tRex.draw(0,0)}if(this.crashed&&this.gameOverPanel){this.gameOverPanel.updateDimensions(this.dimensions.width);this.gameOverPanel.draw(this.altGameModeActive,this.tRex)}}},playIntro(){if(!this.activated&&!this.crashed){this.playingIntro=true;this.tRex.playingIntro=true;const keyframes="@-webkit-keyframes intro { "+"from { width:"+this.tRex.config.width+"px }"+"to { width: "+this.dimensions.width+"px }"+"}";document.styleSheets[0].insertRule(keyframes,0);this.containerEl.addEventListener(Runner.events.ANIM_END,this.startGame.bind(this));this.containerEl.style.webkitAnimation="intro .4s ease-out 1 both";this.containerEl.style.width=this.dimensions.width+"px";this.setPlayStatus(true);this.activated=true}else if(this.crashed){this.restart()}},startGame(){if(this.isArcadeMode()){this.setArcadeMode()}this.toggleSpeed();this.runningTime=0;this.playingIntro=false;this.tRex.playingIntro=false;this.containerEl.style.webkitAnimation="";this.playCount++;if(Runner.audioCues){this.generatedSoundFx.background();this.containerEl.setAttribute("title",getA11yString(A11Y_STRINGS.jump))}document.addEventListener(Runner.events.VISIBILITY,this.onVisibilityChange.bind(this));window.addEventListener(Runner.events.BLUR,this.onVisibilityChange.bind(this));window.addEventListener(Runner.events.FOCUS,this.onVisibilityChange.bind(this))},clearCanvas(){this.canvasCtx.clearRect(0,0,this.dimensions.width,this.dimensions.height)},isCanvasInView(){return this.containerEl.getBoundingClientRect().top>Runner.config.CANVAS_IN_VIEW_OFFSET},enableAltGameMode(){Runner.imageSprite=Runner.altGameImageSprite;Runner.spriteDefinition=spriteDefinitionByType[Runner.gameType];if(IS_HIDPI){this.spriteDef=Runner.spriteDefinition.hdpi}else{this.spriteDef=Runner.spriteDefinition.ldpi}this.altGameModeActive=true;this.tRex.enableAltGameMode(this.spriteDef.tRex);this.horizon.enableAltGameMode(this.spriteDef);if(Runner.audioCues){this.generatedSoundFx.background()}},update(){this.updatePending=false;const now=getTimeStamp();let deltaTime=now-(this.time||now);if(this.altGameModeFlashTimer<0||this.altGameModeFlashTimer===0){this.altGameModeFlashTimer=null;this.tRex.setFlashing(false);this.enableAltGameMode()}else if(this.altGameModeFlashTimer>0){this.altGameModeFlashTimer-=deltaTime;this.tRex.update(deltaTime);deltaTime=0}this.time=now;if(this.playing){this.clearCanvas();if(this.altGameModeActive&&this.fadeInTimer<=this.config.FADE_DURATION){this.fadeInTimer+=deltaTime/1e3;this.canvasCtx.globalAlpha=this.fadeInTimer}else{this.canvasCtx.globalAlpha=1}if(this.tRex.jumping){this.tRex.updateJump(deltaTime)}this.runningTime+=deltaTime;const hasObstacles=this.runningTime>this.config.CLEAR_TIME;if(this.tRex.jumpCount===1&&!this.playingIntro){this.playIntro()}if(this.playingIntro){this.horizon.update(0,this.currentSpeed,hasObstacles)}else if(!this.crashed){const showNightMode=this.isDarkMode^this.inverted;deltaTime=!this.activated?0:deltaTime;this.horizon.update(deltaTime,this.currentSpeed,hasObstacles,showNightMode)}let collision=hasObstacles&&checkForCollision(this.horizon.obstacles[0],this.tRex);if(Runner.audioCues&&hasObstacles){const jumpObstacle=this.horizon.obstacles[0].typeConfig.type!=="collectable";if(!this.horizon.obstacles[0].jumpAlerted){const threshold=Runner.isMobileMouseInput?Runner.config.AUDIOCUE_PROXIMITY_THRESHOLD_MOBILE_A11Y:Runner.config.AUDIOCUE_PROXIMITY_THRESHOLD;const adjProximityThreshold=threshold+threshold*Math.log10(this.currentSpeed/Runner.config.SPEED);if(this.horizon.obstacles[0].xPos<adjProximityThreshold){if(jumpObstacle){this.generatedSoundFx.jump()}this.horizon.obstacles[0].jumpAlerted=true}}}if(Runner.isAltGameModeEnabled()&&collision&&this.horizon.obstacles[0].typeConfig.type==="collectable"){this.horizon.removeFirstObstacle();this.tRex.setFlashing(true);collision=false;this.altGameModeFlashTimer=this.config.FLASH_DURATION;this.runningTime=0;if(Runner.audioCues){this.generatedSoundFx.collect()}}if(!collision){this.distanceRan+=this.currentSpeed*deltaTime/this.msPerFrame;if(this.currentSpeed<this.config.MAX_SPEED){this.currentSpeed+=this.config.ACCELERATION}}else{this.gameOver()}const playAchievementSound=this.distanceMeter.update(deltaTime,Math.ceil(this.distanceRan));if(!Runner.audioCues&&playAchievementSound){this.playSound(this.soundFx.SCORE)}if(!Runner.isAltGameModeEnabled()){if(this.invertTimer>this.config.INVERT_FADE_DURATION){this.invertTimer=0;this.invertTrigger=false;this.invert(false)}else if(this.invertTimer){this.invertTimer+=deltaTime}else{const actualDistance=this.distanceMeter.getActualDistance(Math.ceil(this.distanceRan));if(actualDistance>0){this.invertTrigger=!(actualDistance%this.config.INVERT_DISTANCE);if(this.invertTrigger&&this.invertTimer===0){this.invertTimer+=deltaTime;this.invert(false)}}}}}if(this.playing||!this.activated&&this.tRex.blinkCount<Runner.config.MAX_BLINK_COUNT){this.tRex.update(deltaTime);this.scheduleNextUpdate()}},handleEvent(e){return function(evtType,events){switch(evtType){case events.KEYDOWN:case events.TOUCHSTART:case events.POINTERDOWN:this.onKeyDown(e);break;case events.KEYUP:case events.TOUCHEND:case events.POINTERUP:this.onKeyUp(e);break;case events.GAMEPADCONNECTED:this.onGamepadConnected(e);break}}.bind(this)(e.type,Runner.events)},handleCanvasKeyPress(e){if(!this.activated&&!Runner.audioCues){this.toggleSpeed();this.generatedSoundFx=new GeneratedSoundFx;Runner.audioCues=true;Runner.generatedSoundFx=this.generatedSoundFx;Runner.config.CLEAR_TIME*=1.2}else if(e.keyCode&&Runner.keycodes.JUMP[e.keyCode]){this.onKeyDown(e)}},preventScrolling(e){if(e.keyCode===32){e.preventDefault()}},toggleSpeed(){if(Runner.audioCues){const speedChange=Runner.slowDown!==this.slowSpeedCheckbox.checked;if(speedChange){Runner.slowDown=this.slowSpeedCheckbox.checked;const updatedConfig=Runner.slowDown?Runner.slowConfig:Runner.normalConfig;Runner.config=Object.assign(Runner.config,updatedConfig);this.currentSpeed=updatedConfig.SPEED;this.tRex.enableSlowConfig();this.horizon.adjustObstacleSpeed()}if(this.playing){this.disableSpeedToggle(true)}}},showSpeedToggle(e){const isFocusEvent=e&&e.type==="focus";if(Runner.audioCues||isFocusEvent){this.slowSpeedCheckboxLabel.classList.toggle(HIDDEN_CLASS,isFocusEvent?false:!this.crashed)}},disableSpeedToggle(disable){if(disable){this.slowSpeedCheckbox.setAttribute("disabled","disabled")}else{this.slowSpeedCheckbox.removeAttribute("disabled")}},startListening(){this.containerEl.addEventListener(Runner.events.KEYDOWN,this.handleCanvasKeyPress.bind(this));if(!IS_MOBILE){this.containerEl.addEventListener(Runner.events.FOCUS,this.showSpeedToggle.bind(this))}this.canvas.addEventListener(Runner.events.KEYDOWN,this.preventScrolling.bind(this));this.canvas.addEventListener(Runner.events.KEYUP,this.preventScrolling.bind(this));document.addEventListener(Runner.events.KEYDOWN,this);document.addEventListener(Runner.events.KEYUP,this);this.containerEl.addEventListener(Runner.events.TOUCHSTART,this);document.addEventListener(Runner.events.POINTERDOWN,this);document.addEventListener(Runner.events.POINTERUP,this);if(this.isArcadeMode()){window.addEventListener(Runner.events.GAMEPADCONNECTED,this)}},stopListening(){document.removeEventListener(Runner.events.KEYDOWN,this);document.removeEventListener(Runner.events.KEYUP,this);if(this.touchController){this.touchController.removeEventListener(Runner.events.TOUCHSTART,this);this.touchController.removeEventListener(Runner.events.TOUCHEND,this)}this.containerEl.removeEventListener(Runner.events.TOUCHSTART,this);document.removeEventListener(Runner.events.POINTERDOWN,this);document.removeEventListener(Runner.events.POINTERUP,this);if(this.isArcadeMode()){window.removeEventListener(Runner.events.GAMEPADCONNECTED,this)}},onKeyDown(e){if(IS_MOBILE&&this.playing){e.preventDefault()}if(this.isCanvasInView()){if(Runner.keycodes.JUMP[e.keyCode]&&e.target===this.slowSpeedCheckbox){return}if(!this.crashed&&!this.paused){const isMobileMouseInput=IS_MOBILE&&e.type===Runner.events.POINTERDOWN&&e.pointerType==="mouse"&&(e.target===this.containerEl||IS_IOS&&(e.target===this.touchController||e.target===this.canvas));if(Runner.keycodes.JUMP[e.keyCode]||e.type===Runner.events.TOUCHSTART||isMobileMouseInput){e.preventDefault();if(!this.playing){if(!this.touchController&&e.type===Runner.events.TOUCHSTART){this.createTouchController()}if(isMobileMouseInput){this.handleCanvasKeyPress(e)}this.loadSounds();this.setPlayStatus(true);this.update();if(window.errorPageController){errorPageController.trackEasterEgg()}}if(!this.tRex.jumping&&!this.tRex.ducking){if(Runner.audioCues){this.generatedSoundFx.cancelFootSteps()}else{this.playSound(this.soundFx.BUTTON_PRESS)}this.tRex.startJump(this.currentSpeed)}}else if(this.playing&&Runner.keycodes.DUCK[e.keyCode]){e.preventDefault();if(this.tRex.jumping){this.tRex.setSpeedDrop()}else if(!this.tRex.jumping&&!this.tRex.ducking){this.tRex.setDuck(true)}}}}},onKeyUp(e){const keyCode=String(e.keyCode);const isjumpKey=Runner.keycodes.JUMP[keyCode]||e.type===Runner.events.TOUCHEND||e.type===Runner.events.POINTERUP;if(this.isRunning()&&isjumpKey){this.tRex.endJump()}else if(Runner.keycodes.DUCK[keyCode]){this.tRex.speedDrop=false;this.tRex.setDuck(false)}else if(this.crashed){const deltaTime=getTimeStamp()-this.time;if(this.isCanvasInView()&&(Runner.keycodes.RESTART[keyCode]||this.isLeftClickOnCanvas(e)||deltaTime>=this.config.GAMEOVER_CLEAR_TIME&&Runner.keycodes.JUMP[keyCode])){this.handleGameOverClicks(e)}}else if(this.paused&&isjumpKey){this.tRex.reset();this.play()}},onGamepadConnected(e){if(!this.pollingGamepads){this.pollGamepadState()}},pollGamepadState(){const gamepads=navigator.getGamepads();this.pollActiveGamepad(gamepads);this.pollingGamepads=true;requestAnimationFrame(this.pollGamepadState.bind(this))},pollForActiveGamepad(gamepads){for(let i=0;i<gamepads.length;++i){if(gamepads[i]&&gamepads[i].buttons.length>0&&gamepads[i].buttons[0].pressed){this.gamepadIndex=i;this.pollActiveGamepad(gamepads);return}}},pollActiveGamepad(gamepads){if(this.gamepadIndex===undefined){this.pollForActiveGamepad(gamepads);return}const gamepad=gamepads[this.gamepadIndex];if(!gamepad){this.gamepadIndex=undefined;this.pollForActiveGamepad(gamepads);return}this.pollGamepadButton(gamepad,0,38);if(gamepad.buttons.length>=2){this.pollGamepadButton(gamepad,1,40)}if(gamepad.buttons.length>=10){this.pollGamepadButton(gamepad,9,13)}this.previousGamepad=gamepad},pollGamepadButton(gamepad,buttonIndex,keyCode){const state=gamepad.buttons[buttonIndex].pressed;let previousState=false;if(this.previousGamepad){previousState=this.previousGamepad.buttons[buttonIndex].pressed}if(state!==previousState){const e=new KeyboardEvent(state?Runner.events.KEYDOWN:Runner.events.KEYUP,{keyCode:keyCode});document.dispatchEvent(e)}},handleGameOverClicks(e){if(e.target!==this.slowSpeedCheckbox){e.preventDefault();if(this.distanceMeter.hasClickedOnHighScore(e)&&this.highestScore){if(this.distanceMeter.isHighScoreFlashing()){this.saveHighScore(0,true);this.distanceMeter.resetHighScore()}else{this.distanceMeter.startHighScoreFlashing()}}else{this.distanceMeter.cancelHighScoreFlashing();this.restart()}}},isLeftClickOnCanvas(e){return e.button!=null&&e.button<2&&e.type===Runner.events.POINTERUP&&(e.target===this.canvas||IS_MOBILE&&Runner.audioCues&&e.target===this.containerEl)},scheduleNextUpdate(){if(!this.updatePending){this.updatePending=true;this.raqId=requestAnimationFrame(this.update.bind(this))}},isRunning(){return!!this.raqId},initializeHighScore(highScore){this.syncHighestScore=true;highScore=Math.ceil(highScore);if(highScore<this.highestScore){if(window.errorPageController){errorPageController.updateEasterEggHighScore(this.highestScore)}return}this.highestScore=highScore;this.distanceMeter.setHighScore(this.highestScore)},saveHighScore(distanceRan,opt_resetScore){this.highestScore=Math.ceil(distanceRan);this.distanceMeter.setHighScore(this.highestScore);if(this.syncHighestScore&&window.errorPageController){if(opt_resetScore){errorPageController.resetEasterEggHighScore()}else{errorPageController.updateEasterEggHighScore(this.highestScore)}}},gameOver(){this.playSound(this.soundFx.HIT);vibrate(200);this.stop();this.crashed=true;this.distanceMeter.achievement=false;this.tRex.update(100,Status.CRASHED);if(!this.gameOverPanel){const origSpriteDef=IS_HIDPI?spriteDefinitionByType.original.hdpi:spriteDefinitionByType.original.ldpi;if(this.canvas){if(Runner.isAltGameModeEnabled){this.gameOverPanel=new GameOverPanel(this.canvas,origSpriteDef.textSprite,origSpriteDef.restart,this.dimensions,origSpriteDef.altGameEnd,this.altGameModeActive)}else{this.gameOverPanel=new GameOverPanel(this.canvas,origSpriteDef.textSprite,origSpriteDef.restart,this.dimensions)}}}this.gameOverPanel.draw(this.altGameModeActive,this.tRex);if(this.distanceRan>this.highestScore){this.saveHighScore(this.distanceRan)}this.time=getTimeStamp();if(Runner.audioCues){this.generatedSoundFx.stopAll();announcePhrase(getA11yString(A11Y_STRINGS.gameOver).replace("$1",this.distanceMeter.getActualDistance(this.distanceRan).toString())+" "+getA11yString(A11Y_STRINGS.highScore).replace("$1",this.distanceMeter.getActualDistance(this.highestScore).toString()));this.containerEl.setAttribute("title",getA11yString(A11Y_STRINGS.ariaLabel))}this.showSpeedToggle();this.disableSpeedToggle(false)},stop(){this.setPlayStatus(false);this.paused=true;cancelAnimationFrame(this.raqId);this.raqId=0;if(Runner.audioCues){this.generatedSoundFx.stopAll()}},play(){if(!this.crashed){this.setPlayStatus(true);this.paused=false;this.tRex.update(0,Status.RUNNING);this.time=getTimeStamp();this.update();if(Runner.audioCues){this.generatedSoundFx.background()}}},restart(){if(!this.raqId){this.playCount++;this.runningTime=0;this.setPlayStatus(true);this.toggleSpeed();this.paused=false;this.crashed=false;this.distanceRan=0;this.setSpeed(this.config.SPEED);this.time=getTimeStamp();this.containerEl.classList.remove(Runner.classes.CRASHED);this.clearCanvas();this.distanceMeter.reset();this.horizon.reset();this.tRex.reset();this.playSound(this.soundFx.BUTTON_PRESS);this.invert(true);this.flashTimer=null;this.update();this.gameOverPanel.reset();if(Runner.audioCues){this.generatedSoundFx.background()}this.containerEl.setAttribute("title",getA11yString(A11Y_STRINGS.jump));announcePhrase(getA11yString(A11Y_STRINGS.started))}},setPlayStatus(isPlaying){if(this.touchController){this.touchController.classList.toggle(HIDDEN_CLASS,!isPlaying)}this.playing=isPlaying},isArcadeMode(){return IS_RTL?document.title.indexOf(ARCADE_MODE_URL)===1:document.title===ARCADE_MODE_URL},setArcadeMode(){document.body.classList.add(Runner.classes.ARCADE_MODE);this.setArcadeModeContainerScale()},setArcadeModeContainerScale(){const windowHeight=window.innerHeight;const scaleHeight=windowHeight/this.dimensions.height;const scaleWidth=window.innerWidth/this.dimensions.width;const scale=Math.max(1,Math.min(scaleHeight,scaleWidth));const scaledCanvasHeight=this.dimensions.height*scale;const translateY=Math.ceil(Math.max(0,(windowHeight-scaledCanvasHeight-Runner.config.ARCADE_MODE_INITIAL_TOP_POSITION)*Runner.config.ARCADE_MODE_TOP_POSITION_PERCENT))*window.devicePixelRatio;const cssScale=IS_RTL?-scale+","+scale:scale;this.containerEl.style.transform="scale("+cssScale+") translateY("+translateY+"px)"},onVisibilityChange(e){if(document.hidden||document.webkitHidden||e.type==="blur"||document.visibilityState!=="visible"){this.stop()}else if(!this.crashed){this.tRex.reset();this.play()}},playSound(soundBuffer){if(soundBuffer){const sourceNode=this.audioContext.createBufferSource();sourceNode.buffer=soundBuffer;sourceNode.connect(this.audioContext.destination);sourceNode.start(0)}},invert(reset){const htmlEl=document.firstElementChild;if(reset){htmlEl.classList.toggle(Runner.classes.INVERTED,false);this.invertTimer=0;this.inverted=false}else{this.inverted=htmlEl.classList.toggle(Runner.classes.INVERTED,this.invertTrigger)}}};Runner.updateCanvasScaling=function(canvas,opt_width,opt_height){const context=canvas.getContext("2d");const devicePixelRatio=Math.floor(window.devicePixelRatio)||1;const backingStoreRatio=Math.floor(context.webkitBackingStorePixelRatio)||1;const ratio=devicePixelRatio/backingStoreRatio;if(devicePixelRatio!==backingStoreRatio){const oldWidth=opt_width||canvas.width;const oldHeight=opt_height||canvas.height;canvas.width=oldWidth*ratio;canvas.height=oldHeight*ratio;canvas.style.width=oldWidth+"px";canvas.style.height=oldHeight+"px";context.scale(ratio,ratio);return true}else if(devicePixelRatio===1){canvas.style.width=canvas.width+"px";canvas.style.height=canvas.height+"px"}return false};Runner.isAltGameModeEnabled=function(){return loadTimeData&&loadTimeData.valueExists("enableAltGameMode")};function announcePhrase(phrase){if(Runner.a11yStatusEl){Runner.a11yStatusEl.textContent="";Runner.a11yStatusEl.textContent=phrase}}function getA11yString(stringName){return loadTimeData&&loadTimeData.valueExists(stringName)?loadTimeData.getString(stringName):""}function vibrate(duration){if(IS_MOBILE&&window.navigator.vibrate){window.navigator.vibrate(duration)}}function createCanvas(container,width,height,opt_classname){const canvas=document.createElement("canvas");canvas.className=Runner.classes.CANVAS;canvas.width=width;canvas.height=height;container.appendChild(canvas);return canvas}function decodeBase64ToArrayBuffer(base64String){const len=base64String.length/4*3;const str=atob(base64String);const arrayBuffer=new ArrayBuffer(len);const bytes=new Uint8Array(arrayBuffer);for(let i=0;i<len;i++){bytes[i]=str.charCodeAt(i)}return bytes.buffer}function checkForCollision(obstacle,tRex,opt_canvasCtx){Runner.defaultDimensions.width+obstacle.xPos;const tRexBox=new CollisionBox(tRex.xPos+1,tRex.yPos+1,tRex.config.width-2,tRex.config.height-2);const obstacleBox=new CollisionBox(obstacle.xPos+1,obstacle.yPos+1,obstacle.typeConfig.width*obstacle.size-2,obstacle.typeConfig.height-2);if(boxCompare(tRexBox,obstacleBox)){const collisionBoxes=obstacle.collisionBoxes;let tRexCollisionBoxes=[];if(Runner.isAltGameModeEnabled()){tRexCollisionBoxes=Runner.spriteDefinition.tRex.collisionBoxes}else{tRexCollisionBoxes=tRex.getCollisionBoxes()}for(let t=0;t<tRexCollisionBoxes.length;t++){for(let i=0;i<collisionBoxes.length;i++){const adjTrexBox=createAdjustedCollisionBox(tRexCollisionBoxes[t],tRexBox);const adjObstacleBox=createAdjustedCollisionBox(collisionBoxes[i],obstacleBox);const crashed=boxCompare(adjTrexBox,adjObstacleBox);if(crashed){return[adjTrexBox,adjObstacleBox]}}}}}function createAdjustedCollisionBox(box,adjustment){return new CollisionBox(box.x+adjustment.x,box.y+adjustment.y,box.width,box.height)}function boxCompare(tRexBox,obstacleBox){let crashed=false;tRexBox.x;tRexBox.y;const obstacleBoxX=obstacleBox.x;obstacleBox.y;if(tRexBox.x<obstacleBoxX+obstacleBox.width&&tRexBox.x+tRexBox.width>obstacleBoxX&&tRexBox.y<obstacleBox.y+obstacleBox.height&&tRexBox.height+tRexBox.y>obstacleBox.y){crashed=true}return crashed}
// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let showingDetails=false;let lastData=null;function toggleHelpBox(){showingDetails=!showingDetails;assert(lastData);B(getHtml(lastData,showingDetails),getRequiredElement("content"))}function diagnoseErrors(){if(window.errorPageController){window.errorPageController.diagnoseErrorsButtonClick()}}function portalSignin(){if(window.errorPageController){window.errorPageController.portalSigninButtonClick()}}let isSubFrame=false;if(window.top.location!==window.location){document.documentElement.setAttribute("subframe","");isSubFrame=true}function updateForDnsProbe(newData){onTemplateDataReceived(newData)}function getMainFrameErrorCssClass(showingDetails){return showingDetails?"showing-details":""}function getMainFrameErrorIconCssClass(data){return isSubFrame?"":data.iconClass}function getSubFrameErrorIconCssClass(data){return isSubFrame?data.iconClass:""}function shouldShowSuggestionsSummaryList(data){return!!data.suggestionsSummaryList&&data.suggestionsSummaryList.length>0}function getSuggestionsSummaryItemCssClass(data){assert(data.suggestionsSummaryList);return data.suggestionsSummaryList.length===1?"single-suggestion":""}function reloadButtonClick(e){const url=e.target.dataset["url"];if(window.errorPageController){window.errorPageController.reloadButtonClick()}else{assert(url);window.location.href=url}}function downloadButtonClick(){if(window.errorPageController){window.errorPageController.downloadButtonClick();const downloadButton=getRequiredElement("download-button");downloadButton.disabled=true;downloadButton.textContent=downloadButton.disabledText}}function detailsButtonClick(){if(window.errorPageController){window.errorPageController.detailsButtonClick()}toggleHelpBox()}function setAutoFetchState(scheduled,canSchedule){getRequiredElement("cancel-save-page-button").classList.toggle(HIDDEN_CLASS,!scheduled);getRequiredElement("save-page-for-later-button").classList.toggle(HIDDEN_CLASS,!canSchedule)}function savePageLaterClick(){assert(window.errorPageController);window.errorPageController.savePageForLater()}function cancelSavePageClick(){assert(window.errorPageController);window.errorPageController.cancelSavePage();setAutoFetchState(false,true)}function shouldShowControlButtons(data){const downloadButtonVisible=!!data.downloadButton&&!!data.downloadButton.msg;const reloadButtonVisible=!!data.reloadButton&&!!data.reloadButton.msg;return reloadButtonVisible||downloadButtonVisible}function shouldShowDetailsButton(data){return!!data.suggestionsDetails&&data.suggestionsDetails.length>0}function getDetailsButtonCssClass(data){return shouldShowControlButtons(data)?"":"singular"}function getDetailsButtonText(data,showingDetails){assert(data.details);assert(data.hideDetails);return showingDetails?data.hideDetails:data.details}function getButtonsCssClass(){let primaryControlOnLeft=true;return primaryControlOnLeft?"suggested-left":"suggested-right"}function onDocumentLoad(){onTemplateDataReceived(window.loadTimeDataRaw)}function onTemplateDataReceived(newData){lastData=newData;B(getHtml(lastData,showingDetails),getRequiredElement("content"));if(!isSubFrame&&newData.iconClass==="icon-offline"){document.documentElement.classList.add("offline");loadTimeData.data=newData;new Runner(".interstitial-wrapper")}}function getHtml(data,showingDetails){return x`
    <div id="main-frame-error" class="interstitial-wrapper ${getMainFrameErrorCssClass(showingDetails)}">
      <div id="main-content">
        <div class="icon ${getMainFrameErrorIconCssClass(data)}"></div>
        <div id="main-message">
          <h1>
            <span .innerHTML="${data.heading.msg}"></span>
          </h1>
          ${data.summary?x`
            <p .innerHTML="${data.summary.msg}"></p>
          `:""}

          ${shouldShowSuggestionsSummaryList(data)?x`
            <div id="suggestions-list">
              <p>${data.suggestionsSummaryListHeader}</p>
              <ul class="${getSuggestionsSummaryItemCssClass(data)}">
                ${data.suggestionsSummaryList.map((item=>x`
                  <li .innerHTML="${item.summary}"></li>
                `))}
              </ul>
            </div>
          `:""}

          <div class="error-code">${data.errorCode}</div>

          ${data.savePageLater?x`
            <div id="save-page-for-later-button">
              <a class="link-button" @click="${savePageLaterClick}">
                ${data.savePageLater.savePageMsg}
              </a>
            </div>
            <div id="cancel-save-page-button" class="hidden"
                @click="${cancelSavePageClick}"
                .innerHTML="${data.savePageLater.cancelMsg}">
            </div>
          `:""}
        </div>
      </div>
      <div id="buttons" class="nav-wrapper ${getButtonsCssClass()}">
        <div id="control-buttons" ?hidden="${!shouldShowControlButtons(data)}">
          ${data.reloadButton?x`
            <button id="reload-button"
                class="blue-button text-button"
                @click="${reloadButtonClick}"
                data-url="${data.reloadButton.reloadUrl}">
              ${data.reloadButton.msg}
            </button>
          `:""}
          ${data.downloadButton?x`
            <button id="download-button"
                class="blue-button text-button"
                @click="${downloadButtonClick}"
                .disabledText="${data.downloadButton.disabledMsg}">
              ${data.downloadButton.msg}
            </button>
          `:""}
        </div>
        ${shouldShowDetailsButton(data)?x`
          <button id="details-button" class="secondary-button text-button
              small-link ${getDetailsButtonCssClass(data)}"
              @click="${detailsButtonClick}">
            ${getDetailsButtonText(data,showingDetails)}
          </button>
        `:""}
      </div>
      ${data.suggestionsDetails?x`
        <div id="details">
          ${data.suggestionsDetails.map((item=>x`
            <div class="suggestions">
              <div class="suggestion-header" .innerHTML="${item.header}"></div>
              <div class="suggestion-body" .innerHTML="${item.body}"></div>
            </div>
          `))}
        </div>
      `:""}
    </div>
    ${data.summary?x`
      <div id="sub-frame-error">
        <!-- Show details when hovering over the icon, in case the details are
             hidden because they're too large. -->
        <div class="icon ${getSubFrameErrorIconCssClass(data)}"></div>
        <div id="sub-frame-error-details" .innerHTML="${data.summary.msg}">
        </div>
      </div>
    `:""}
  `}Object.assign(window,{diagnoseErrors:diagnoseErrors,portalSignin:portalSignin,toggleHelpBox:toggleHelpBox,updateForDnsProbe:updateForDnsProbe});document.addEventListener("DOMContentLoaded",onDocumentLoad);</script>

</head>
<body class="neterror" style="font-family: &#39;Segoe UI&#39;,Arial,&#39;Microsoft Yahei&#39;,sans-serif; font-size: 75%">
  <div id="content"><!---->
    <div id="main-frame-error" class="interstitial-wrapper ">
      <div id="main-content">
        <div class="icon icon-generic"></div>
        <div id="main-message">
          <h1>
            <span>未连接到互联网</span>
          </h1>
          <!--?lit$310839142$-->
            <p>代理服务器出现问题，或者地址有误。</p>
          

          <!--?lit$310839142$-->
            <div id="suggestions-list">
              <p><!--?lit$310839142$-->请试试以下办法：</p>
              <ul class="">
                <!--?lit$310839142$--><!---->
                  <li>联系系统管理员</li>
                <!----><!---->
                  <li><a href="chrome-error://chromewebdata/#buttons" onclick="toggleHelpBox()">检查代理服务器地址</a></li>
                <!----><!---->
                  <li><a href="javascript:diagnoseErrors()" id="diagnose-link">运行 Windows 网络诊断</a></li>
                <!---->
              </ul>
            </div>
          

          <div class="error-code"><!--?lit$310839142$-->ERR_PROXY_CONNECTION_FAILED</div>

          <!--?lit$310839142$-->
        </div>
      </div>
      <div id="buttons" class="nav-wrapper suggested-left">
        <div id="control-buttons" hidden="">
          <!--?lit$310839142$-->
          <!--?lit$310839142$-->
        </div>
        <!--?lit$310839142$-->
          <button id="details-button" class="secondary-button text-button
              small-link singular">
            <!--?lit$310839142$-->详情
          </button>
        
      </div>
      <!--?lit$310839142$-->
        <div id="details">
          <!--?lit$310839142$--><!---->
            <div class="suggestions">
              <div class="suggestion-header">如果您使用代理服务器…</div>
              <div class="suggestion-body">依次转到 Chrome 菜单 &gt;“<span>设置</span>”&gt;“<span>显示高级设置…</span>”&gt;“<span>更改代理服务器设置…</span>”&gt;“LAN 设置”，然后取消选中“为 LAN 使用代理服务器”。</div>
            </div>
          <!---->
        </div>
      
    </div>
    <!--?lit$310839142$-->
      <div id="sub-frame-error">
        <!-- Show details when hovering over the icon, in case the details are
             hidden because they're too large. -->
        <div class="icon "></div>
        <div id="sub-frame-error-details">代理服务器出现问题，或者地址有误。</div>
      </div>
    
  </div>
  <div id="offline-resources">
    <img id="offline-resources-1x" src="">
    <img id="offline-resources-2x" src="">
    <template id="audio-resources"></template>
  </div>


<script>var loadTimeDataRaw = {"details":"详情","errorCode":"ERR_PROXY_CONNECTION_FAILED","fontfamily":"'Segoe UI',Arial,'Microsoft Yahei',sans-serif","fontfamilyMd":"'Segoe UI',Arial,'Microsoft Yahei',sans-serif","fontsize":"75%","heading":{"msg":"未连接到互联网"},"hideDetails":"隐藏详细信息","iconClass":"icon-generic","language":"zh","suggestionsDetails":[{"body":"依次转到 Chrome 菜单 >“\u003Cspan>设置\u003C/span>”>“\u003Cspan>显示高级设置…\u003C/span>”>“\u003Cspan>更改代理服务器设置…\u003C/span>”>“LAN 设置”，然后取消选中“为 LAN 使用代理服务器”。","header":"如果您使用代理服务器…"}],"suggestionsSummaryList":[{"summary":"联系系统管理员"},{"summary":"\u003Ca href=\"#buttons\" onclick=\"toggleHelpBox()\">检查代理服务器地址\u003C/a>"},{"summary":"\u003Ca href=\"javascript:diagnoseErrors()\" id=\"diagnose-link\">运行 Windows 网络诊断\u003C/a>"}],"suggestionsSummaryListHeader":"请试试以下办法：","summary":{"msg":"代理服务器出现问题，或者地址有误。"},"textdirection":"ltr","title":"pan.baidu.com"};</script></body></html>